From 985311d9f06a67e36a3cd922569de6ada18f8aaa Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 26 Feb 2020 11:02:32 +0300 Subject: [PATCH] [FIR] Implement delegate inference --- .../AbstractManyCandidatesInferenceSession.kt | 120 ++++++++++++++++++ .../fir/resolve/inference/FirCallCompleter.kt | 13 ++ .../FirDelegatedPropertyInferenceSession.kt | 92 ++++++++++++++ ...rCallCompletionResultsWriterTransformer.kt | 83 +++++++++++- .../body/resolve/FirBodyResolveTransformer.kt | 2 +- .../FirDeclarationsResolveTransformer.kt | 116 ++++++++++++----- .../FirExpressionsResolveTransformer.kt | 19 +-- .../resolve/delegates/delegateInference.kt | 27 ++++ .../resolve/delegates/delegateInference.txt | 63 +++++++++ .../resolve/delegates/delegateWithLambda.kt | 16 +++ .../resolve/delegates/delegateWithLambda.txt | 43 +++++++ .../resolve/delegates/provideDelegate.kt | 19 +++ .../resolve/delegates/provideDelegate.txt | 46 +++++++ .../{problems => }/delegateTypeMismatch.kt | 0 .../{problems => }/delegateTypeMismatch.txt | 6 +- .../fir/FirDiagnosticsTestGenerated.java | 28 ++++ ...DiagnosticsWithLightTreeTestGenerated.java | 28 ++++ ...FirDiagnosticsWithStdlibTestGenerated.java | 10 +- .../PropertyDelegateWithPrivateSet.fir.kt | 2 +- 19 files changed, 673 insertions(+), 60 deletions(-) create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt create mode 100644 compiler/fir/resolve/testData/resolve/delegates/delegateInference.kt create mode 100644 compiler/fir/resolve/testData/resolve/delegates/delegateInference.txt create mode 100644 compiler/fir/resolve/testData/resolve/delegates/delegateWithLambda.kt create mode 100644 compiler/fir/resolve/testData/resolve/delegates/delegateWithLambda.txt create mode 100644 compiler/fir/resolve/testData/resolve/delegates/provideDelegate.kt create mode 100644 compiler/fir/resolve/testData/resolve/delegates/provideDelegate.txt rename compiler/fir/resolve/testData/resolveWithStdlib/{problems => }/delegateTypeMismatch.kt (100%) rename compiler/fir/resolve/testData/resolveWithStdlib/{problems => }/delegateTypeMismatch.txt (89%) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt new file mode 100644 index 00000000000..0a8e0212e11 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt @@ -0,0 +1,120 @@ +/* + * Copyright 2010-2020 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.fir.resolve.inference + +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirResolvable +import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents +import org.jetbrains.kotlin.fir.resolve.calls.Candidate +import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate +import org.jetbrains.kotlin.fir.resolve.calls.candidate +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.coneTypeUnsafe +import org.jetbrains.kotlin.fir.visitors.transformSingle +import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem +import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor +import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter +import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage +import org.jetbrains.kotlin.utils.addToStdlib.safeAs + +abstract class AbstractManyCandidatesInferenceSession( + protected val components: BodyResolveComponents, + initialCall: FirExpression, + private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer, +) : FirInferenceSession() { + private val errorCalls: MutableList = mutableListOf() + private val partiallyResolvedCalls: MutableList = mutableListOf() + private val completedCalls: MutableSet = mutableSetOf() + + init { + val initialCandidate = (initialCall as? FirResolvable) + ?.calleeReference + ?.safeAs() + ?.candidate + if (initialCandidate != null) { + partiallyResolvedCalls += initialCall as FirResolvable + } + } + + private val unitType: ConeKotlinType = components.session.builtinTypes.unitType.coneTypeUnsafe() + + override val currentConstraintSystem: ConstraintStorage + get() = partiallyResolvedCalls.lastOrNull() + ?.calleeReference + ?.safeAs() + ?.candidate + ?.system + ?.currentStorage() + ?: ConstraintStorage.Empty + + private lateinit var resultingConstraintSystem: NewConstraintSystem + + override fun shouldRunCompletion(candidate: Candidate): Boolean { + return false + } + + override fun addCompetedCall(call: T) where T : FirResolvable, T : FirStatement { + // do nothing + } + + final override fun addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement { + partiallyResolvedCalls += call + } + + final override fun addErrorCall(call: T) where T : FirResolvable, T : FirStatement { + errorCalls += call + } + + final override fun callCompleted(call: T): Boolean where T : FirResolvable, T : FirStatement { + return !completedCalls.add(call) + } + + protected open fun prepareForCompletion( + commonSystem: NewConstraintSystem, + partiallyResolvedCalls: List + ) { + // do nothing + } + + fun completeCandidates(): List { + fun runCompletion(constraintSystem: NewConstraintSystem, atoms: List) { + components.callCompleter.completer.complete( + constraintSystem.asConstraintSystemCompleterContext(), + KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL, + atoms, + unitType + ) { + postponedArgumentsAnalyzer.analyze( + constraintSystem.asPostponedArgumentsAnalyzerContext(), + it, + (atoms.first() as FirResolvable).candidate + ) + } + } + + @Suppress("UNCHECKED_CAST") + val resolvedCalls = partiallyResolvedCalls as List + val commonSystem = components.inferenceComponents.createConstraintSystem().apply { + addOtherSystem(currentConstraintSystem) + } + prepareForCompletion(commonSystem, resolvedCalls) + @Suppress("UNCHECKED_CAST") + runCompletion(commonSystem, resolvedCalls as List) + resultingConstraintSystem = commonSystem + return resolvedCalls + } + + protected val FirResolvable.candidate: Candidate + get() = candidate()!! + + fun createFinalSubstitutor(): ConeSubstitutor { + return resultingConstraintSystem.asReadOnlyStorage() + .buildAbstractResultingSubstitutor(components.inferenceComponents.ctx) as ConeSubstitutor + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt index be203fda73f..f8e4d3e23aa 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt @@ -118,6 +118,19 @@ class FirCallCompleter( } } + fun createCompletionResultsWriter( + substitutor: ConeSubstitutor, + mode: FirCallCompletionResultsWriterTransformer.Mode = FirCallCompletionResultsWriterTransformer.Mode.Normal + ): FirCallCompletionResultsWriterTransformer { + return FirCallCompletionResultsWriterTransformer( + session, substitutor, returnTypeCalculator, + inferenceComponents.approximator, + integerOperatorsTypeUpdater, + integerLiteralTypeApproximator, + mode + ) + } + fun createPostponedArgumentsAnalyzer(): PostponedArgumentsAnalyzer { return PostponedArgumentsAnalyzer( LambdaAnalyzerImpl(), inferenceComponents, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt new file mode 100644 index 00000000000..59d5e6cb2db --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt @@ -0,0 +1,92 @@ +/* + * Copyright 2010-2020 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.fir.resolve.inference + +import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject +import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirResolvable +import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.references.FirNamedReference +import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents +import org.jetbrains.kotlin.fir.resolve.calls.Candidate +import org.jetbrains.kotlin.fir.resolve.defaultType +import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.ConeTypeVariableTypeConstructor +import org.jetbrains.kotlin.fir.types.coneTypeSafe +import org.jetbrains.kotlin.fir.types.coneTypeUnsafe +import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder +import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem +import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage +import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition +import org.jetbrains.kotlin.util.OperatorNameConventions + +class FirDelegatedPropertyInferenceSession( + val property: FirProperty, + initialCall: FirExpression, + components: BodyResolveComponents, + postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer, +) : AbstractManyCandidatesInferenceSession(components, initialCall, postponedArgumentsAnalyzer) { + val expectedType: ConeKotlinType? by lazy { property.returnTypeRef.coneTypeSafe() } + + override fun inferPostponedVariables( + lambda: ResolvedLambdaAtom, + initialStorage: ConstraintStorage + ): Map = emptyMap() + + override fun shouldCompleteResolvedSubAtomsOf(call: T): Boolean where T : FirResolvable, T : FirStatement = true + + override fun prepareForCompletion(commonSystem: NewConstraintSystem, partiallyResolvedCalls: List) { + val csBuilder = commonSystem.getBuilder() + for (call in partiallyResolvedCalls) { + val candidate = call.candidate + when ((call.calleeReference as FirNamedReference).name) { + OperatorNameConventions.GET_VALUE -> candidate.addConstraintsForGetValueMethod(csBuilder) + OperatorNameConventions.SET_VALUE -> candidate.addConstraintsForSetValueMethod(csBuilder) + } + } + } + + private fun Candidate.addConstraintsForGetValueMethod(commonSystem: ConstraintSystemBuilder) { + if (expectedType != null) { + val accessor = symbol.fir as? FirSimpleFunction ?: return + val unsubstitutedReturnType = accessor.returnTypeRef.coneTypeSafe() ?: return + + val substitutedReturnType = substitutor.substituteOrSelf(unsubstitutedReturnType) + commonSystem.addSubtypeConstraint(substitutedReturnType, expectedType!!, SimpleConstraintSystemConstraintPosition) + } + + addConstraintForThis(commonSystem) + } + + + private fun Candidate.addConstraintsForSetValueMethod(commonSystem: ConstraintSystemBuilder) { + if (expectedType != null) { + val accessor = symbol.fir as? FirSimpleFunction ?: return + val unsubstitutedParameterType = accessor.valueParameters.getOrNull(2)?.returnTypeRef?.coneTypeSafe() ?: return + + val substitutedReturnType = substitutor.substituteOrSelf(unsubstitutedParameterType) + commonSystem.addSubtypeConstraint(substitutedReturnType, expectedType!!, SimpleConstraintSystemConstraintPosition) + } + + addConstraintForThis(commonSystem) + } + + private fun Candidate.addConstraintForThis(commonSystem: ConstraintSystemBuilder) { + val typeOfThis: ConeKotlinType = property.receiverTypeRef?.coneTypeUnsafe() + ?: when (val container = components.container) { + is FirRegularClass -> container.defaultType() + is FirAnonymousObject -> container.defaultType() + else -> null + } ?: components.session.builtinTypes.nullableNothingType.coneTypeUnsafe() + val valueParameterForThis = (symbol as? FirFunctionSymbol<*>)?.fir?.valueParameters?.firstOrNull() ?: return + val substitutedType = substitutor.substituteOrSelf(valueParameterForThis.returnTypeRef.coneTypeUnsafe()) + commonSystem.addSubtypeConstraint(typeOfThis, substitutedType, SimpleConstraintSystemConstraintPosition) + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index a96a1f7c7dd..09fac32f815 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType import org.jetbrains.kotlin.fir.resolve.inference.returnType import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor -import org.jetbrains.kotlin.fir.resolve.substitution.substituteOrNull import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType @@ -28,9 +27,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl -import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult -import org.jetbrains.kotlin.fir.visitors.compose -import org.jetbrains.kotlin.fir.visitors.transformSingle +import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.types.AbstractTypeApproximator import org.jetbrains.kotlin.types.TypeApproximatorConfiguration import org.jetbrains.kotlin.types.Variance @@ -43,8 +40,15 @@ class FirCallCompletionResultsWriterTransformer( private val typeApproximator: AbstractTypeApproximator, private val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater, private val integerApproximator: IntegerLiteralTypeApproximationTransformer, + private val mode: Mode = Mode.Normal ) : FirAbstractTreeTransformer(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { + private val declarationWriter by lazy { FirDeclarationCompletionResultsWriter(finalSubstitutor) } + + enum class Mode { + Normal, DelegatedPropertyCompletion + } + override fun transformQualifiedAccessExpression( qualifiedAccessExpression: FirQualifiedAccessExpression, data: ExpectedArgumentType?, @@ -87,7 +91,7 @@ class FirCallCompletionResultsWriterTransformer( private fun FirResolvedTypeRef.substituteTypeRef( candidate: Candidate, ): FirResolvedTypeRef { - val initialType = candidate.substitutor.substituteOrNull(type) + val initialType = candidate.substitutor.substituteOrSelf(type) val finalType = finalSubstitutor.substituteOrNull(initialType)?.let { substitutedType -> typeApproximator.approximateToSuperType( substitutedType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference, @@ -208,9 +212,34 @@ class FirCallCompletionResultsWriterTransformer( result.replaceTypeRef(resultType) result.replaceTypeArguments(typeArguments) + if (mode == Mode.DelegatedPropertyCompletion) { + calleeReference.candidateSymbol.fir.transformSingle(declarationWriter, null) + val typeUpdater = TypeUpdaterForDelegateArguments() + result.transformArguments(typeUpdater, null) + result.transformExplicitReceiver(typeUpdater, null) + } + return result.compose() } + private inner class TypeUpdaterForDelegateArguments : FirTransformer() { + override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { + return element.compose() + } + + override fun transformQualifiedAccessExpression( + qualifiedAccessExpression: FirQualifiedAccessExpression, + data: Nothing? + ): CompositeTransformResult { + val originalType = qualifiedAccessExpression.typeRef.coneTypeUnsafe() + val substitutedReceiverType = finalSubstitutor.substituteOrNull(originalType) ?: return qualifiedAccessExpression.compose() + qualifiedAccessExpression.replaceTypeRef( + qualifiedAccessExpression.typeRef.resolvedTypeFromPrototype(substitutedReceiverType) + ) + return qualifiedAccessExpression.compose() + } + } + private fun FirTypeRef.substitute(candidate: Candidate): ConeKotlinType = coneTypeUnsafe() .let { candidate.substitutor.substituteOrSelf(it) } @@ -383,3 +412,47 @@ private fun ConeKotlinType.approximateIfPossible(expectedType: ConeKotlinType?) } else { this } + +class FirDeclarationCompletionResultsWriter(private val finalSubstitutor: ConeSubstitutor) : FirDefaultTransformer() { + override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { + return element.compose() + } + + override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?): CompositeTransformResult { + simpleFunction.transformReturnTypeRef(this, data) + simpleFunction.transformValueParameters(this, data) + simpleFunction.transformReceiverTypeRef(this, data) + return simpleFunction.compose() + } + + override fun transformProperty(property: FirProperty, data: Nothing?): CompositeTransformResult { + property.transformGetter(this, data) + property.transformSetter(this, data) + property.transformReturnTypeRef(this, data) + property.transformReceiverTypeRef(this, data) + return property.compose() + } + + override fun transformPropertyAccessor( + propertyAccessor: FirPropertyAccessor, + data: Nothing? + ): CompositeTransformResult { + propertyAccessor.transformReturnTypeRef(this, data) + propertyAccessor.transformValueParameters(this, data) + return propertyAccessor.compose() + } + + override fun transformValueParameter( + valueParameter: FirValueParameter, + data: Nothing? + ): CompositeTransformResult { + valueParameter.transformReturnTypeRef(this, data) + return valueParameter.compose() + } + + override fun transformTypeRef(typeRef: FirTypeRef, data: Nothing?): CompositeTransformResult { + return finalSubstitutor.substituteOrNull(typeRef.coneTypeUnsafe())?.let { + typeRef.resolvedTypeFromPrototype(it) + }?.compose() ?: typeRef.compose() + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt index 1399445af63..00c33cead9a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt @@ -150,7 +150,7 @@ open class FirBodyResolveTransformer( wrappedDelegateExpression: FirWrappedDelegateExpression, data: ResolutionMode ): CompositeTransformResult { - return expressionsTransformer.transformWrappedDelegateExpression(wrappedDelegateExpression, data) + return declarationsTransformer.transformWrappedDelegateExpression(wrappedDelegateExpression, data) } override fun transformConstExpression(constExpression: FirConstExpression, data: ResolutionMode): CompositeTransformResult { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 29955296010..4afb66c138a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -14,16 +14,13 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic -import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.expressions.FirReturnExpression -import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildReturnExpression import org.jetbrains.kotlin.fir.expressions.builder.buildUnitExpression +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.* -import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverKind -import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue -import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue -import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue +import org.jetbrains.kotlin.fir.resolve.calls.* +import org.jetbrains.kotlin.fir.resolve.inference.FirDelegatedPropertyInferenceSession import org.jetbrains.kotlin.fir.resolve.inference.extractLambdaInfoFromFunctionalType import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.transformers.* @@ -104,21 +101,25 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) dataFlowAnalyzer.enterProperty(property) withFullBodyResolve { withScopeCleanup(localScopes) { - components.withContainer(property) { - withScopeCleanup(localScopes) { + if (property.delegate != null) { localScopes.addIfNotNull(primaryConstructorParametersScope) - property.transformChildrenWithoutAccessors(returnTypeRef) - property.transformInitializer(integerLiteralTypeApproximator, null) - } - if (property.initializer != null) { - storeVariableReturnType(property) - } - withScopeCleanup(localScopes) { - localScopes.add(FirLocalScope().apply { - storeBackingField(property) - }) - property.transformAccessors() + transformPropertyWithDelegate(property) + } else { + withScopeCleanup(localScopes) { + localScopes.addIfNotNull(primaryConstructorParametersScope) + property.transformChildrenWithoutAccessors(returnTypeRef) + property.transformInitializer(integerLiteralTypeApproximator, null) + } + if (property.initializer != null) { + storeVariableReturnType(property) + } + withScopeCleanup(localScopes) { + localScopes.add(FirLocalScope().apply { + storeBackingField(property) + }) + property.transformAccessors() + } } } property.replaceResolvePhase(transformerPhase) @@ -130,17 +131,68 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } } + private fun transformPropertyWithDelegate(property: FirProperty) { + property.transformDelegate(transformer, ResolutionMode.ContextDependent) + + val delegateExpression = property.delegate!! + + val inferenceSession = FirDelegatedPropertyInferenceSession( + property, + delegateExpression, + components, + callCompleter.createPostponedArgumentsAnalyzer() + ) + + components.inferenceComponents.withInferenceSession(inferenceSession) { + property.transformAccessors() + val completedCalls = inferenceSession.completeCandidates() + val finalSubstitutor = inferenceSession.createFinalSubstitutor() + val callCompletionResultsWriter = components.callCompleter.createCompletionResultsWriter( + finalSubstitutor, + mode = FirCallCompletionResultsWriterTransformer.Mode.DelegatedPropertyCompletion + ) + completedCalls.forEach { + it.transformSingle(callCompletionResultsWriter, null) + } + val declarationCompletionResultsWriter = FirDeclarationCompletionResultsWriter(finalSubstitutor) + property.transformSingle(declarationCompletionResultsWriter, null) + } + property.transformOtherChildren(transformer, ResolutionMode.ContextIndependent) + } + + override fun transformWrappedDelegateExpression( + wrappedDelegateExpression: FirWrappedDelegateExpression, + data: ResolutionMode, + ): CompositeTransformResult { + val delegateProvider = wrappedDelegateExpression.delegateProvider.transformSingle(transformer, ResolutionMode.ContextDependent) + when (val calleeReference = (delegateProvider as FirResolvable).calleeReference) { + is FirResolvedNamedReference -> return delegateProvider.compose() + is FirNamedReferenceWithCandidate -> { + val candidate = calleeReference.candidate + if (!candidate.system.hasContradiction) { + return delegateProvider.compose() + } + } + } + + return wrappedDelegateExpression.expression.transform(transformer, ResolutionMode.ContextDependent) + } + private fun transformLocalVariable(variable: FirProperty): CompositeTransformResult { assert(variable.isLocal) - val resolutionMode = withExpectedType(variable.returnTypeRef) - variable.transformInitializer(transformer, resolutionMode) - .transformDelegate(transformer, resolutionMode) - .transformOtherChildren(transformer, resolutionMode) - .transformInitializer(integerLiteralTypeApproximator, null) - if (variable.initializer != null) { - storeVariableReturnType(variable) + if (variable.delegate != null) { + transformPropertyWithDelegate(variable) + } else { + val resolutionMode = withExpectedType(variable.returnTypeRef) + variable.transformInitializer(transformer, resolutionMode) + .transformDelegate(transformer, resolutionMode) + .transformOtherChildren(transformer, resolutionMode) + .transformInitializer(integerLiteralTypeApproximator, null) + if (variable.initializer != null) { + storeVariableReturnType(variable) + } + variable.transformAccessors() } - variable.transformAccessors() localScopes.lastOrNull()?.storeVariable(variable) variable.replaceResolvePhase(transformerPhase) dataFlowAnalyzer.exitLocalVariableDeclaration(variable) @@ -191,7 +243,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } } else { transformFunctionWithGivenSignature(accessor, expectedReturnTypeRef) - } as CompositeTransformResult + } } private fun FirDeclaration.resolveStatus(status: FirDeclarationStatus, containingClass: FirClass<*>? = null): FirDeclarationStatus { @@ -263,6 +315,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } containingClass = oldContainingClass primaryConstructorParametersScope = oldConstructorScope + @Suppress("UNCHECKED_CAST") result as CompositeTransformResult } } @@ -278,6 +331,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) val result = withLabelAndReceiverType(null, anonymousObject, type) { transformDeclaration(anonymousObject, data) } + @Suppress("UNCHECKED_CAST") result as CompositeTransformResult } } @@ -344,7 +398,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) private fun > transformFunctionWithGivenSignature( function: F, - returnTypeRef: FirTypeRef + returnTypeRef: FirTypeRef, ): CompositeTransformResult { if (function is FirSimpleFunction) { localScopes.lastOrNull()?.storeFunction(function) @@ -372,6 +426,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) return withScopeCleanup(localScopes) { localScopes += FirLocalScope() dataFlowAnalyzer.enterFunction(function) + @Suppress("UNCHECKED_CAST") transformDeclaration(function, data).also { val result = it.single as FirFunction<*> dataFlowAnalyzer.exitFunction(result)?.let { controlFlowGraph -> @@ -383,6 +438,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): CompositeTransformResult { if (implicitTypeOnly) return constructor.compose() + @Suppress("UNCHECKED_CAST") return transformFunction(constructor, data) as CompositeTransformResult } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index b9ceec56d8f..18132d2b26e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -37,7 +37,10 @@ import org.jetbrains.kotlin.fir.symbols.invoke import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.* import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl -import org.jetbrains.kotlin.fir.visitors.* +import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult +import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer +import org.jetbrains.kotlin.fir.visitors.compose +import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance @@ -478,20 +481,6 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : return transformedGetClassCall.compose() } - override fun transformWrappedDelegateExpression( - wrappedDelegateExpression: FirWrappedDelegateExpression, - data: ResolutionMode, - ): CompositeTransformResult { - transformExpression(wrappedDelegateExpression, data) - with(wrappedDelegateExpression) { - val delegateProviderTypeRef = delegateProvider.typeRef - val useDelegateProvider = delegateProviderTypeRef is FirResolvedTypeRef && - delegateProviderTypeRef !is FirErrorTypeRef && - delegateProviderTypeRef.type !is ConeKotlinErrorType - return if (useDelegateProvider) delegateProvider.compose() else expression.compose() - } - } - override fun transformConstExpression( constExpression: FirConstExpression, data: ResolutionMode, diff --git a/compiler/fir/resolve/testData/resolve/delegates/delegateInference.kt b/compiler/fir/resolve/testData/resolve/delegates/delegateInference.kt new file mode 100644 index 00000000000..d4cb4c7154c --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/delegates/delegateInference.kt @@ -0,0 +1,27 @@ +import kotlin.reflect.KProperty + +class FreezableVar(private var value: T) { + operator fun getValue(thisRef: Any, property: KProperty<*>): T = value + + operator fun setValue(thisRef: Any, property: KProperty<*>, value: T) { + this.value = value + } +} + +class LocalFreezableVar(private var value: T) { + operator fun getValue(thisRef: Nothing?, property: KProperty<*>): T = value + + operator fun setValue(thisRef: Nothing?, property: KProperty<*>, value: T) { + this.value = value + } +} + +class Test { + var x: Boolean by FreezableVar(true) + var y by FreezableVar("") +} + +fun test() { + var x: Boolean by LocalFreezableVar(true) + var y by LocalFreezableVar("") +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/delegates/delegateInference.txt b/compiler/fir/resolve/testData/resolve/delegates/delegateInference.txt new file mode 100644 index 00000000000..7477238af4c --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/delegates/delegateInference.txt @@ -0,0 +1,63 @@ +FILE: delegateInference.kt + public final class FreezableVar : R|kotlin/Any| { + public constructor(value: R|T|): R|FreezableVar| { + super() + } + + private final var value: R|T| = R|/value| + private get(): R|T| + private set(value: R|T|): R|kotlin/Unit| + + public final operator fun getValue(thisRef: R|kotlin/Any|, property: R|kotlin/reflect/KProperty<*>|): R|T| { + ^getValue this@R|/FreezableVar|.R|/FreezableVar.value| + } + + public final operator fun setValue(thisRef: R|kotlin/Any|, property: R|kotlin/reflect/KProperty<*>|, value: R|T|): R|kotlin/Unit| { + this@R|/FreezableVar|.R|/FreezableVar.value| = R|/value| + } + + } + public final class LocalFreezableVar : R|kotlin/Any| { + public constructor(value: R|T|): R|LocalFreezableVar| { + super() + } + + private final var value: R|T| = R|/value| + private get(): R|T| + private set(value: R|T|): R|kotlin/Unit| + + public final operator fun getValue(thisRef: R|kotlin/Nothing?|, property: R|kotlin/reflect/KProperty<*>|): R|T| { + ^getValue this@R|/LocalFreezableVar|.R|/LocalFreezableVar.value| + } + + public final operator fun setValue(thisRef: R|kotlin/Nothing?|, property: R|kotlin/reflect/KProperty<*>|, value: R|T|): R|kotlin/Unit| { + this@R|/LocalFreezableVar|.R|/LocalFreezableVar.value| = R|/value| + } + + } + public final class Test : R|kotlin/Any| { + public constructor(): R|Test| { + super() + } + + public final var x: R|kotlin/Boolean|by R|/FreezableVar.FreezableVar|(Boolean(true)) + public get(): R|kotlin/Boolean| { + ^ D|/Test.x|.R|FakeOverride|(this@R|/Test|, ::R|/Test.x|) + } + public set(: R|kotlin/Boolean|): R|kotlin/Unit| { + D|/Test.x|.R|FakeOverride|(this@R|/Test|, ::R|/Test.x|, R|/x|) + } + + public final var y: R|kotlin/String|by R|/FreezableVar.FreezableVar|(String()) + public get(): R|kotlin/String| { + ^ D|/Test.y|.R|FakeOverride|(this@R|/Test|, ::R|/Test.y|) + } + public set(: R|kotlin/String|): R|kotlin/Unit| { + D|/Test.y|.R|FakeOverride|(this@R|/Test|, ::R|/Test.y|, R|/y|) + } + + } + public final fun test(): R|kotlin/Unit| { + lvar x: R|kotlin/Boolean|by R|/LocalFreezableVar.LocalFreezableVar|(Boolean(true)) + lvar y: R|kotlin/String|by R|/LocalFreezableVar.LocalFreezableVar|(String()) + } diff --git a/compiler/fir/resolve/testData/resolve/delegates/delegateWithLambda.kt b/compiler/fir/resolve/testData/resolve/delegates/delegateWithLambda.kt new file mode 100644 index 00000000000..6f9052fd8a7 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/delegates/delegateWithLambda.kt @@ -0,0 +1,16 @@ +import kotlin.reflect.KProperty + +class LazyDelegate(val value: T) { + operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value +} + +fun lazy(block: () -> T): LazyDelegate = LazyDelegate(block()) + +fun getAny(): Any? = null + +class Test { + val x by lazy { + val y = getAny() as? String ?: "" + y + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/delegates/delegateWithLambda.txt b/compiler/fir/resolve/testData/resolve/delegates/delegateWithLambda.txt new file mode 100644 index 00000000000..c6caf41b225 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/delegates/delegateWithLambda.txt @@ -0,0 +1,43 @@ +FILE: delegateWithLambda.kt + public final class LazyDelegate : R|kotlin/Any| { + public constructor(value: R|T|): R|LazyDelegate| { + super() + } + + public final val value: R|T| = R|/value| + public get(): R|T| + + public final operator fun getValue(thisRef: R|kotlin/Any?|, property: R|kotlin/reflect/KProperty<*>|): R|T| { + ^getValue this@R|/LazyDelegate|.R|/LazyDelegate.value| + } + + } + public final fun lazy(block: R|() -> T|): R|LazyDelegate| { + ^lazy R|/LazyDelegate.LazyDelegate|(R|/block|.R|FakeOverride|()) + } + public final fun getAny(): R|kotlin/Any?| { + ^getAny Null(null) + } + public final class Test : R|kotlin/Any| { + public constructor(): R|Test| { + super() + } + + public final val x: R|kotlin/String|by R|/lazy|( = lazy@fun (): R|kotlin/String| { + lval y: R|kotlin/String| = when (lval : R|kotlin/String?| = (R|/getAny|() as? R|kotlin/String|)) { + ==($subj$, Null(null)) -> { + String() + } + else -> { + R|/| + } + } + + ^ R|/y| + } + ) + public get(): R|kotlin/String| { + ^ D|/Test.x|.R|FakeOverride|(this@R|/Test|, ::R|/Test.x|) + } + + } diff --git a/compiler/fir/resolve/testData/resolve/delegates/provideDelegate.kt b/compiler/fir/resolve/testData/resolve/delegates/provideDelegate.kt new file mode 100644 index 00000000000..68c31000880 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/delegates/provideDelegate.kt @@ -0,0 +1,19 @@ +import kotlin.reflect.KProperty + +class Delegate(var value: T) { + operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value + + operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: T) { + value = newValue + } +} + +class DelegateProvider(val value: T) { + operator fun provideDelegate(thisRef: Any?, property: KProperty<*>): Delegate = Delegate(value) +} + +fun delegate(value: T): DelegateProvider = DelegateProvider(value) + +class A { + val x by delegate(1) +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/delegates/provideDelegate.txt b/compiler/fir/resolve/testData/resolve/delegates/provideDelegate.txt new file mode 100644 index 00000000000..cee40e52d3e --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/delegates/provideDelegate.txt @@ -0,0 +1,46 @@ +FILE: provideDelegate.kt + public final class Delegate : R|kotlin/Any| { + public constructor(value: R|T|): R|Delegate| { + super() + } + + public final var value: R|T| = R|/value| + public get(): R|T| + public set(value: R|T|): R|kotlin/Unit| + + public final operator fun getValue(thisRef: R|kotlin/Any?|, property: R|kotlin/reflect/KProperty<*>|): R|T| { + ^getValue this@R|/Delegate|.R|/Delegate.value| + } + + public final operator fun setValue(thisRef: R|kotlin/Any?|, property: R|kotlin/reflect/KProperty<*>|, newValue: R|T|): R|kotlin/Unit| { + this@R|/Delegate|.R|/Delegate.value| = R|/newValue| + } + + } + public final class DelegateProvider : R|kotlin/Any| { + public constructor(value: R|T|): R|DelegateProvider| { + super() + } + + public final val value: R|T| = R|/value| + public get(): R|T| + + public final operator fun provideDelegate(thisRef: R|kotlin/Any?|, property: R|kotlin/reflect/KProperty<*>|): R|Delegate| { + ^provideDelegate R|/Delegate.Delegate|(this@R|/DelegateProvider|.R|/DelegateProvider.value|) + } + + } + public final fun delegate(value: R|T|): R|DelegateProvider| { + ^delegate R|/DelegateProvider.DelegateProvider|(R|/value|) + } + public final class A : R|kotlin/Any| { + public constructor(): R|A| { + super() + } + + public final val x: R|kotlin/Int|by R|/delegate|(Int(1)).R|FakeOverride|>|(this@R|/A|, ::R|/A.x|) + public get(): R|kotlin/Int| { + ^ D|/A.x|.R|FakeOverride|(this@R|/A|, ::R|/A.x|) + } + + } diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/problems/delegateTypeMismatch.kt b/compiler/fir/resolve/testData/resolveWithStdlib/delegateTypeMismatch.kt similarity index 100% rename from compiler/fir/resolve/testData/resolveWithStdlib/problems/delegateTypeMismatch.kt rename to compiler/fir/resolve/testData/resolveWithStdlib/delegateTypeMismatch.kt diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/problems/delegateTypeMismatch.txt b/compiler/fir/resolve/testData/resolveWithStdlib/delegateTypeMismatch.txt similarity index 89% rename from compiler/fir/resolve/testData/resolveWithStdlib/problems/delegateTypeMismatch.txt rename to compiler/fir/resolve/testData/resolveWithStdlib/delegateTypeMismatch.txt index 9203f9f8469..8b1879f8c16 100644 --- a/compiler/fir/resolve/testData/resolveWithStdlib/problems/delegateTypeMismatch.txt +++ b/compiler/fir/resolve/testData/resolveWithStdlib/delegateTypeMismatch.txt @@ -33,12 +33,12 @@ FILE: delegateTypeMismatch.kt ) } - public final var classifierNamePolicy: R|ClassifierNamePolicy|by this@R|/A|.R|/A.property|(Q|ClassifierNamePolicy.SOURCE_CODE_QUALIFIED|) + public final var classifierNamePolicy: R|ClassifierNamePolicy|by this@R|/A|.R|/A.property|(Q|ClassifierNamePolicy.SOURCE_CODE_QUALIFIED|) public get(): R|ClassifierNamePolicy| { - ^ D|/A.classifierNamePolicy|.R|FakeOverride|(this@R|/A|, ::R|/A.classifierNamePolicy|) + ^ D|/A.classifierNamePolicy|.R|FakeOverride|(this@R|/A|, ::R|/A.classifierNamePolicy|) } public set(: R|ClassifierNamePolicy|): R|kotlin/Unit| { - D|/A.classifierNamePolicy|.#(this@R|/A|, ::R|/A.classifierNamePolicy|, R|/classifierNamePolicy|) + D|/A.classifierNamePolicy|.R|FakeOverride|(this@R|/A|, ::R|/A.classifierNamePolicy|, R|/classifierNamePolicy|) } public final var typeNormalizer: by # KotlinType|>(property@fun (): R|ERROR CLASS: Unresolved name: it| { diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index c5547aee58a..a319725ac62 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -572,6 +572,34 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { } } + @TestMetadata("compiler/fir/resolve/testData/resolve/delegates") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Delegates extends AbstractFirDiagnosticsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInDelegates() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/delegates"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("delegateInference.kt") + public void testDelegateInference() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/delegates/delegateInference.kt"); + } + + @TestMetadata("delegateWithLambda.kt") + public void testDelegateWithLambda() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/delegates/delegateWithLambda.kt"); + } + + @TestMetadata("provideDelegate.kt") + public void testProvideDelegate() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/delegates/provideDelegate.kt"); + } + } + @TestMetadata("compiler/fir/resolve/testData/resolve/diagnostics") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index 714625bff04..0830e575163 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -572,6 +572,34 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos } } + @TestMetadata("compiler/fir/resolve/testData/resolve/delegates") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Delegates extends AbstractFirDiagnosticsWithLightTreeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInDelegates() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/delegates"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("delegateInference.kt") + public void testDelegateInference() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/delegates/delegateInference.kt"); + } + + @TestMetadata("delegateWithLambda.kt") + public void testDelegateWithLambda() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/delegates/delegateWithLambda.kt"); + } + + @TestMetadata("provideDelegate.kt") + public void testProvideDelegate() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/delegates/provideDelegate.kt"); + } + } + @TestMetadata("compiler/fir/resolve/testData/resolve/diagnostics") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index 4aca220f6c2..6339b7b5981 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -83,6 +83,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic runTest("compiler/fir/resolve/testData/resolveWithStdlib/concurrentMapOfAliases.kt"); } + @TestMetadata("delegateTypeMismatch.kt") + public void testDelegateTypeMismatch() throws Exception { + runTest("compiler/fir/resolve/testData/resolveWithStdlib/delegateTypeMismatch.kt"); + } + @TestMetadata("delegationByMap.kt") public void testDelegationByMap() throws Exception { runTest("compiler/fir/resolve/testData/resolveWithStdlib/delegationByMap.kt"); @@ -685,11 +690,6 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic runTest("compiler/fir/resolve/testData/resolveWithStdlib/problems/cloneArray.kt"); } - @TestMetadata("delegateTypeMismatch.kt") - public void testDelegateTypeMismatch() throws Exception { - runTest("compiler/fir/resolve/testData/resolveWithStdlib/problems/delegateTypeMismatch.kt"); - } - @TestMetadata("invokePriority.kt") public void testInvokePriority() throws Exception { runTest("compiler/fir/resolve/testData/resolveWithStdlib/problems/invokePriority.kt"); diff --git a/compiler/testData/diagnostics/testsWithStdLib/PropertyDelegateWithPrivateSet.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/PropertyDelegateWithPrivateSet.fir.kt index 9c108459050..40ccffe49e1 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/PropertyDelegateWithPrivateSet.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/PropertyDelegateWithPrivateSet.fir.kt @@ -8,5 +8,5 @@ class My { val another: String = delegate var delegateWithBackingField: String by kotlin.properties.Delegates.notNull() - private set(arg) { field = arg } + private set(arg) { field = arg } }