rr/vd/KT-57514

Revert "Create SimpleFunctionDescriptorImpl under nonCancelableSection"

This reverts commit d959b3a289b24487dba2e36da94a34a0dbb4661e.

Revert "Create PropertyDescriptorImpl under nonCancelableSection"

This reverts commit 362e8c2151c8e18009463fd51b995cce27ac8eb5.

Merge-request: KT-MR-9772
Merged-by: Vladimir Dolzhenko <Vladimir.Dolzhenko@jetbrains.com>
This commit is contained in:
Vladimir Dolzhenko
2023-04-29 06:39:59 +00:00
committed by Space Team
parent ec3e13a091
commit adc5fe6e4e
3 changed files with 382 additions and 429 deletions
@@ -19,8 +19,6 @@ package org.jetbrains.kotlin.resolve;
import com.google.common.collect.HashMultimap; import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.intellij.openapi.diagnostic.ControlFlowException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import kotlin.Pair; import kotlin.Pair;
@@ -317,89 +315,81 @@ public class DescriptorResolver {
@NotNull Annotations additionalAnnotations, @NotNull Annotations additionalAnnotations,
@Nullable InferenceSession inferenceSession @Nullable InferenceSession inferenceSession
) { ) {
try { KotlinType varargElementType = null;
KotlinType varargElementType = null; KotlinType variableType = type;
KotlinType variableType = type; if (valueParameter.hasModifier(VARARG_KEYWORD)) {
if (valueParameter.hasModifier(VARARG_KEYWORD)) { varargElementType = type;
varargElementType = type; variableType = getVarargParameterType(type);
variableType = getVarargParameterType(type);
}
Annotations valueParameterAnnotations = resolveValueParameterAnnotations(scope, valueParameter, trace, additionalAnnotations);
KtDestructuringDeclaration destructuringDeclaration = valueParameter.getDestructuringDeclaration();
Function0<List<VariableDescriptor>> destructuringVariables;
if (destructuringDeclaration != null) {
if (!languageVersionSettings.supportsFeature(LanguageFeature.DestructuringLambdaParameters)) {
trace.report(Errors.UNSUPPORTED_FEATURE.on(valueParameter,
TuplesKt.to(LanguageFeature.DestructuringLambdaParameters, languageVersionSettings)));
}
destructuringVariables = () -> {
ReceiverParameterDescriptor dispatchReceiver = owner.getDispatchReceiverParameter();
assert dispatchReceiver == null || dispatchReceiver.getContainingDeclaration() instanceof ScriptDescriptor
: "Destructuring declarations are only be parsed for lambdas, and they must not have a dispatch receiver";
LexicalScope scopeForDestructuring =
ScopeUtilsKt.createScopeForDestructuring(scope, owner.getExtensionReceiverParameter());
List<VariableDescriptor> result =
destructuringDeclarationResolver.resolveLocalVariablesFromDestructuringDeclaration(
scope,
destructuringDeclaration, new TransientReceiver(type), /* initializer = */ null,
ExpressionTypingContext.newContext(
trace, scopeForDestructuring, DataFlowInfoFactory.EMPTY, TypeUtils.NO_EXPECTED_TYPE,
languageVersionSettings, dataFlowValueFactory, inferenceSession
)
);
modifiersChecker.withTrace(trace).checkModifiersForDestructuringDeclaration(destructuringDeclaration);
return result;
};
}
else {
destructuringVariables = null;
}
Name parameterName;
if (destructuringDeclaration == null) {
// NB: val/var for parameter is only allowed in primary constructors where single underscore names are still prohibited.
// The problem with val/var is that when lazy resolve try to find their descriptor, it searches through the member scope
// of containing class where, it can not find a descriptor with special name.
// Thus, to preserve behavior, we don't use a special name for val/var.
parameterName = !valueParameter.hasValOrVar() && UnderscoreUtilKt.isSingleUnderscore(valueParameter)
? Name.special("<anonymous parameter " + index + ">")
: KtPsiUtil.safeName(valueParameter.getName());
}
else {
parameterName = Name.special("<name for destructuring parameter " + index + ">");
}
ValueParameterDescriptorImpl valueParameterDescriptor = ValueParameterDescriptorImpl.createWithDestructuringDeclarations(
owner,
null,
index,
valueParameterAnnotations,
parameterName,
variableType,
valueParameter.hasDefaultValue(),
valueParameter.hasModifier(CROSSINLINE_KEYWORD),
valueParameter.hasModifier(NOINLINE_KEYWORD),
varargElementType,
KotlinSourceElementKt.toSourceElement(valueParameter),
destructuringVariables
);
trace.record(BindingContext.VALUE_PARAMETER, valueParameter, valueParameterDescriptor);
return valueParameterDescriptor;
} }
catch (Exception e) {
if (e instanceof ControlFlowException) { Annotations valueParameterAnnotations = resolveValueParameterAnnotations(scope, valueParameter, trace, additionalAnnotations);
throw new IllegalStateException("Method should be run under nonCancelableSection", e);
KtDestructuringDeclaration destructuringDeclaration = valueParameter.getDestructuringDeclaration();
Function0<List<VariableDescriptor>> destructuringVariables;
if (destructuringDeclaration != null) {
if (!languageVersionSettings.supportsFeature(LanguageFeature.DestructuringLambdaParameters)) {
trace.report(Errors.UNSUPPORTED_FEATURE.on(valueParameter,
TuplesKt.to(LanguageFeature.DestructuringLambdaParameters, languageVersionSettings)));
} }
throw e;
destructuringVariables = () -> {
ReceiverParameterDescriptor dispatchReceiver = owner.getDispatchReceiverParameter();
assert dispatchReceiver == null || dispatchReceiver.getContainingDeclaration() instanceof ScriptDescriptor
: "Destructuring declarations are only be parsed for lambdas, and they must not have a dispatch receiver";
LexicalScope scopeForDestructuring =
ScopeUtilsKt.createScopeForDestructuring(scope, owner.getExtensionReceiverParameter());
List<VariableDescriptor> result =
destructuringDeclarationResolver.resolveLocalVariablesFromDestructuringDeclaration(
scope,
destructuringDeclaration, new TransientReceiver(type), /* initializer = */ null,
ExpressionTypingContext.newContext(
trace, scopeForDestructuring, DataFlowInfoFactory.EMPTY, TypeUtils.NO_EXPECTED_TYPE,
languageVersionSettings, dataFlowValueFactory, inferenceSession
)
);
modifiersChecker.withTrace(trace).checkModifiersForDestructuringDeclaration(destructuringDeclaration);
return result;
};
} }
else {
destructuringVariables = null;
}
Name parameterName;
if (destructuringDeclaration == null) {
// NB: val/var for parameter is only allowed in primary constructors where single underscore names are still prohibited.
// The problem with val/var is that when lazy resolve try to find their descriptor, it searches through the member scope
// of containing class where, it can not find a descriptor with special name.
// Thus, to preserve behavior, we don't use a special name for val/var.
parameterName = !valueParameter.hasValOrVar() && UnderscoreUtilKt.isSingleUnderscore(valueParameter)
? Name.special("<anonymous parameter " + index + ">")
: KtPsiUtil.safeName(valueParameter.getName());
}
else {
parameterName = Name.special("<name for destructuring parameter " + index + ">");
}
ValueParameterDescriptorImpl valueParameterDescriptor = ValueParameterDescriptorImpl.createWithDestructuringDeclarations(
owner,
null,
index,
valueParameterAnnotations,
parameterName,
variableType,
valueParameter.hasDefaultValue(),
valueParameter.hasModifier(CROSSINLINE_KEYWORD),
valueParameter.hasModifier(NOINLINE_KEYWORD),
varargElementType,
KotlinSourceElementKt.toSourceElement(valueParameter),
destructuringVariables
);
trace.record(BindingContext.VALUE_PARAMETER, valueParameter, valueParameterDescriptor);
return valueParameterDescriptor;
} }
@NotNull @NotNull
@@ -923,150 +913,148 @@ public class DescriptorResolver {
annotationSplitter.getOtherAnnotations()) annotationSplitter.getOtherAnnotations())
); );
return ProgressManager.getInstance().computeInNonCancelableSection(() -> { PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create( container,
container, propertyAnnotations,
propertyAnnotations, modality,
modality, visibility,
visibility, isVar,
isVar, KtPsiUtil.safeName(variableDeclaration.getName()),
KtPsiUtil.safeName(variableDeclaration.getName()), CallableMemberDescriptor.Kind.DECLARATION,
CallableMemberDescriptor.Kind.DECLARATION, KotlinSourceElementKt.toSourceElement(variableDeclaration),
KotlinSourceElementKt.toSourceElement(variableDeclaration), modifierList != null && modifierList.hasModifier(KtTokens.LATEINIT_KEYWORD),
modifierList != null && modifierList.hasModifier(KtTokens.LATEINIT_KEYWORD), modifierList != null && modifierList.hasModifier(KtTokens.CONST_KEYWORD),
modifierList != null && modifierList.hasModifier(KtTokens.CONST_KEYWORD), modifierList != null && PsiUtilsKt.hasExpectModifier(modifierList) && container instanceof PackageFragmentDescriptor ||
modifierList != null && PsiUtilsKt.hasExpectModifier(modifierList) && container instanceof PackageFragmentDescriptor || container instanceof ClassDescriptor && ((ClassDescriptor) container).isExpect(),
container instanceof ClassDescriptor && ((ClassDescriptor) container).isExpect(), modifierList != null && PsiUtilsKt.hasActualModifier(modifierList),
modifierList != null && PsiUtilsKt.hasActualModifier(modifierList), modifierList != null && modifierList.hasModifier(KtTokens.EXTERNAL_KEYWORD),
modifierList != null && modifierList.hasModifier(KtTokens.EXTERNAL_KEYWORD), propertyInfo.getHasDelegate()
propertyInfo.getHasDelegate() );
);
List<TypeParameterDescriptorImpl> typeParameterDescriptors; List<TypeParameterDescriptorImpl> typeParameterDescriptors;
LexicalScope scopeForDeclarationResolutionWithTypeParameters; LexicalScope scopeForDeclarationResolutionWithTypeParameters;
LexicalScope scopeForInitializerResolutionWithTypeParameters; LexicalScope scopeForInitializerResolutionWithTypeParameters;
KotlinType receiverType = null; KotlinType receiverType = null;
{ {
List<KtTypeParameter> typeParameters = variableDeclaration.getTypeParameters(); List<KtTypeParameter> typeParameters = variableDeclaration.getTypeParameters();
if (typeParameters.isEmpty()) { if (typeParameters.isEmpty()) {
scopeForDeclarationResolutionWithTypeParameters = scopeForDeclarationResolution; scopeForDeclarationResolutionWithTypeParameters = scopeForDeclarationResolution;
scopeForInitializerResolutionWithTypeParameters = scopeForInitializerResolution; scopeForInitializerResolutionWithTypeParameters = scopeForInitializerResolution;
typeParameterDescriptors = Collections.emptyList(); typeParameterDescriptors = Collections.emptyList();
}
else {
LexicalWritableScope writableScopeForDeclarationResolution = new LexicalWritableScope(
scopeForDeclarationResolution, container, false, new TraceBasedLocalRedeclarationChecker(trace, overloadChecker),
LexicalScopeKind.PROPERTY_HEADER);
LexicalWritableScope writableScopeForInitializerResolution = new LexicalWritableScope(
scopeForInitializerResolution, container, false, LocalRedeclarationChecker.DO_NOTHING.INSTANCE,
LexicalScopeKind.PROPERTY_HEADER);
typeParameterDescriptors = resolveTypeParametersForDescriptor(
propertyDescriptor,
scopeForDeclarationResolution, typeParameters, trace);
for (TypeParameterDescriptor descriptor : typeParameterDescriptors) {
writableScopeForDeclarationResolution.addClassifierDescriptor(descriptor);
writableScopeForInitializerResolution.addClassifierDescriptor(descriptor);
}
writableScopeForDeclarationResolution.freeze();
writableScopeForInitializerResolution.freeze();
resolveGenericBounds(variableDeclaration, propertyDescriptor, writableScopeForDeclarationResolution, typeParameterDescriptors, trace);
scopeForDeclarationResolutionWithTypeParameters = writableScopeForDeclarationResolution;
scopeForInitializerResolutionWithTypeParameters = writableScopeForInitializerResolution;
}
} }
else {
LexicalWritableScope writableScopeForDeclarationResolution = new LexicalWritableScope(
scopeForDeclarationResolution, container, false, new TraceBasedLocalRedeclarationChecker(trace, overloadChecker),
LexicalScopeKind.PROPERTY_HEADER);
LexicalWritableScope writableScopeForInitializerResolution = new LexicalWritableScope(
scopeForInitializerResolution, container, false, LocalRedeclarationChecker.DO_NOTHING.INSTANCE,
LexicalScopeKind.PROPERTY_HEADER);
typeParameterDescriptors = resolveTypeParametersForDescriptor(
propertyDescriptor,
scopeForDeclarationResolution, typeParameters, trace);
for (TypeParameterDescriptor descriptor : typeParameterDescriptors) {
writableScopeForDeclarationResolution.addClassifierDescriptor(descriptor);
writableScopeForInitializerResolution.addClassifierDescriptor(descriptor);
}
writableScopeForDeclarationResolution.freeze();
writableScopeForInitializerResolution.freeze();
resolveGenericBounds(variableDeclaration, propertyDescriptor, writableScopeForDeclarationResolution, typeParameterDescriptors, trace);
scopeForDeclarationResolutionWithTypeParameters = writableScopeForDeclarationResolution;
scopeForInitializerResolutionWithTypeParameters = writableScopeForInitializerResolution;
}
}
KtTypeReference receiverTypeRef = variableDeclaration.getReceiverTypeReference(); KtTypeReference receiverTypeRef = variableDeclaration.getReceiverTypeReference();
ReceiverParameterDescriptor receiverDescriptor = null; ReceiverParameterDescriptor receiverDescriptor = null;
if (receiverTypeRef != null) {
receiverType = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, receiverTypeRef, trace, true);
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER));
receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER)
);
}
List<KtContextReceiver> contextReceivers = variableDeclaration.getContextReceivers();
List<ReceiverParameterDescriptor> contextReceiverDescriptors = IntStream.range(0, contextReceivers.size()).mapToObj(index -> {
KtContextReceiver contextReceiver = contextReceivers.get(index);
KtTypeReference typeReference = contextReceiver.typeReference();
if (typeReference == null) {
return null;
}
KotlinType type = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, typeReference, trace, true);
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, type.getAnnotations(), EnumSet.of(RECEIVER));
return DescriptorFactory.createContextReceiverParameterForCallable(
propertyDescriptor, type, contextReceiver.labelNameAsName(), splitter.getAnnotationsForTarget(RECEIVER), index
);
}).collect(Collectors.toList());
if (languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) {
Multimap<String, ReceiverParameterDescriptor> nameToReceiverMap = HashMultimap.create();
if (receiverTypeRef != null) { if (receiverTypeRef != null) {
receiverType = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, receiverTypeRef, trace, true); String receiverName = receiverTypeRef.nameForReceiverLabel();
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER)); if (receiverName != null) {
receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable( nameToReceiverMap.put(receiverName, receiverDescriptor);
propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER) }
);
} }
for (int i = 0; i < contextReceivers.size(); i++) {
List<KtContextReceiver> contextReceivers = variableDeclaration.getContextReceivers(); String contextReceiverName = contextReceivers.get(i).name();
List<ReceiverParameterDescriptor> contextReceiverDescriptors = IntStream.range(0, contextReceivers.size()).mapToObj(index -> { if (contextReceiverName != null) {
KtContextReceiver contextReceiver = contextReceivers.get(index); nameToReceiverMap.put(contextReceiverName, contextReceiverDescriptors.get(i));
KtTypeReference typeReference = contextReceiver.typeReference();
if (typeReference == null) {
return null;
} }
KotlinType type = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, typeReference, trace, true);
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, type.getAnnotations(), EnumSet.of(RECEIVER));
return DescriptorFactory.createContextReceiverParameterForCallable(
propertyDescriptor, type, contextReceiver.labelNameAsName(), splitter.getAnnotationsForTarget(RECEIVER), index
);
}).collect(Collectors.toList());
if (languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) {
Multimap<String, ReceiverParameterDescriptor> nameToReceiverMap = HashMultimap.create();
if (receiverTypeRef != null) {
String receiverName = receiverTypeRef.nameForReceiverLabel();
if (receiverName != null) {
nameToReceiverMap.put(receiverName, receiverDescriptor);
}
}
for (int i = 0; i < contextReceivers.size(); i++) {
String contextReceiverName = contextReceivers.get(i).name();
if (contextReceiverName != null) {
nameToReceiverMap.put(contextReceiverName, contextReceiverDescriptors.get(i));
}
}
trace.record(DESCRIPTOR_TO_CONTEXT_RECEIVER_MAP, propertyDescriptor, nameToReceiverMap);
} }
trace.record(DESCRIPTOR_TO_CONTEXT_RECEIVER_MAP, propertyDescriptor, nameToReceiverMap);
}
LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor); LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor);
KotlinType propertyType = propertyInfo.getVariableType(); KotlinType propertyType = propertyInfo.getVariableType();
KotlinType typeIfKnown = propertyType != null ? propertyType : variableTypeAndInitializerResolver.resolveTypeNullable( KotlinType typeIfKnown = propertyType != null ? propertyType : variableTypeAndInitializerResolver.resolveTypeNullable(
propertyDescriptor, scopeForInitializer, propertyDescriptor, scopeForInitializer,
variableDeclaration, dataFlowInfo, inferenceSession, variableDeclaration, dataFlowInfo, inferenceSession,
trace, /* local = */ false trace, /* local = */ false
); );
PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor( PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(
scopeForDeclarationResolutionWithTypeParameters, scopeForDeclarationResolutionWithTypeParameters,
variableDeclaration, variableDeclaration,
propertyDescriptor, propertyDescriptor,
annotationSplitter, annotationSplitter,
trace, trace,
typeIfKnown, typeIfKnown,
propertyInfo.getPropertyGetter(), propertyInfo.getPropertyGetter(),
propertyInfo.getHasDelegate(), propertyInfo.getHasDelegate(),
inferenceSession inferenceSession
); );
KotlinType type = typeIfKnown != null ? typeIfKnown : getter.getReturnType(); KotlinType type = typeIfKnown != null ? typeIfKnown : getter.getReturnType();
assert type != null : "At least getter type must be initialized via resolvePropertyGetterDescriptor"; assert type != null : "At least getter type must be initialized via resolvePropertyGetterDescriptor";
variableTypeAndInitializerResolver.setConstantForVariableIfNeeded( variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(
propertyDescriptor, scopeForInitializer, variableDeclaration, dataFlowInfo, type, inferenceSession, trace propertyDescriptor, scopeForInitializer, variableDeclaration, dataFlowInfo, type, inferenceSession, trace
); );
propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(container), receiverDescriptor, propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(container), receiverDescriptor,
contextReceiverDescriptors); contextReceiverDescriptors);
PropertySetterDescriptor setter = resolvePropertySetterDescriptor( PropertySetterDescriptor setter = resolvePropertySetterDescriptor(
scopeForDeclarationResolutionWithTypeParameters, scopeForDeclarationResolutionWithTypeParameters,
variableDeclaration, variableDeclaration,
propertyDescriptor, propertyDescriptor,
annotationSplitter, annotationSplitter,
trace, trace,
propertyInfo.getPropertySetter(), propertyInfo.getPropertySetter(),
propertyInfo.getHasDelegate(), propertyInfo.getHasDelegate(),
inferenceSession inferenceSession
); );
propertyDescriptor.initialize( propertyDescriptor.initialize(
getter, setter, getter, setter,
new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(FIELD), propertyDescriptor), new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(FIELD), propertyDescriptor),
new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(PROPERTY_DELEGATE_FIELD), propertyDescriptor) new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(PROPERTY_DELEGATE_FIELD), propertyDescriptor)
); );
trace.record(BindingContext.VARIABLE, variableDeclaration, propertyDescriptor); trace.record(BindingContext.VARIABLE, variableDeclaration, propertyDescriptor);
return propertyDescriptor; return propertyDescriptor;
});
} }
@NotNull @NotNull
@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import com.google.common.collect.HashMultimap import com.google.common.collect.HashMultimap
import com.intellij.openapi.diagnostic.ControlFlowException
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.util.ThrowableComputable import com.intellij.openapi.util.ThrowableComputable
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.util.AstLoadingFilter import com.intellij.util.AstLoadingFilter
@@ -73,7 +71,6 @@ import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
import java.util.* import java.util.*
class FunctionDescriptorResolver( class FunctionDescriptorResolver(
private val typeResolver: TypeResolver, private val typeResolver: TypeResolver,
private val descriptorResolver: DescriptorResolver, private val descriptorResolver: DescriptorResolver,
@@ -132,21 +129,19 @@ class FunctionDescriptorResolver(
CallableMemberDescriptor.Kind.DECLARATION, CallableMemberDescriptor.Kind.DECLARATION,
function.toSourceElement() function.toSourceElement()
) )
return computeInNonCancelableSection { initializeFunctionDescriptorAndExplicitReturnType(
initializeFunctionDescriptorAndExplicitReturnType( containingDescriptor,
containingDescriptor, scope,
scope, function,
function, functionDescriptor,
functionDescriptor, trace,
trace, expectedFunctionType,
expectedFunctionType, dataFlowInfo,
dataFlowInfo, inferenceSession
inferenceSession )
) initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo, inferenceSession)
initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo, inferenceSession) BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor)
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor) return functionDescriptor
functionDescriptor
}
} }
private fun initializeFunctionReturnTypeBasedOnFunctionBody( private fun initializeFunctionReturnTypeBasedOnFunctionBody(
@@ -187,124 +182,117 @@ class FunctionDescriptorResolver(
dataFlowInfo: DataFlowInfo, dataFlowInfo: DataFlowInfo,
inferenceSession: InferenceSession? inferenceSession: InferenceSession?
) { ) {
try { val headerScope = LexicalWritableScope(
val headerScope = LexicalWritableScope( scope, functionDescriptor, true,
scope, functionDescriptor, true, TraceBasedLocalRedeclarationChecker(trace, overloadChecker), LexicalScopeKind.FUNCTION_HEADER
TraceBasedLocalRedeclarationChecker(trace, overloadChecker), LexicalScopeKind.FUNCTION_HEADER )
val typeParameterDescriptors =
descriptorResolver.resolveTypeParametersForDescriptor(functionDescriptor, headerScope, scope, function.typeParameters, trace)
descriptorResolver.resolveGenericBounds(function, functionDescriptor, headerScope, typeParameterDescriptors, trace)
val receiverTypeRef = function.receiverTypeReference
val receiverType =
if (receiverTypeRef != null) {
typeResolver.resolveType(headerScope, receiverTypeRef, trace, true)
} else {
if (function is KtFunctionLiteral) expectedFunctionType.getReceiverType() else null
}
val contextReceivers = function.contextReceivers
val contextReceiverTypes =
if (function is KtFunctionLiteral) expectedFunctionType.getContextReceiversTypes()
else contextReceivers
.mapNotNull {
val typeReference = it.typeReference() ?: return@mapNotNull null
val type = typeResolver.resolveType(headerScope, typeReference, trace, true)
ContextReceiverTypeWithLabel(type, it.labelNameAsName())
}
val valueParameterDescriptors =
createValueParameterDescriptors(function, functionDescriptor, headerScope, trace, expectedFunctionType, inferenceSession)
headerScope.freeze()
val returnType = function.typeReference?.let { typeResolver.resolveType(headerScope, it, trace, true) }
val visibility = resolveVisibilityFromModifiers(function, getDefaultVisibility(function, container))
val modality = resolveMemberModalityFromModifiers(
function, getDefaultModality(container, visibility, function.hasBody()),
trace.bindingContext, container
)
val contractProvider = getContractProvider(functionDescriptor, trace, scope, dataFlowInfo, function, inferenceSession)
val userData = mutableMapOf<CallableDescriptor.UserDataKey<*>, Any>().apply {
if (contractProvider != null) {
put(ContractProviderKey, contractProvider)
}
if (receiverType != null && expectedFunctionType.functionTypeExpected() && !expectedFunctionType.annotations.isEmpty()) {
put(DslMarkerUtils.FunctionTypeAnnotationsKey, expectedFunctionType.annotations)
}
}
val extensionReceiver = receiverType?.let {
val splitter = AnnotationSplitter(storageManager, it.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
DescriptorFactory.createExtensionReceiverParameterForCallable(
functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER)
) )
}
val typeParameterDescriptors = val contextReceiverDescriptors = contextReceiverTypes.mapIndexedNotNull { index, contextReceiver ->
descriptorResolver.resolveTypeParametersForDescriptor(functionDescriptor, headerScope, scope, function.typeParameters, trace) val splitter = AnnotationSplitter(storageManager, contextReceiver.type.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
descriptorResolver.resolveGenericBounds(function, functionDescriptor, headerScope, typeParameterDescriptors, trace) DescriptorFactory.createContextReceiverParameterForCallable(
functionDescriptor,
val receiverTypeRef = function.receiverTypeReference contextReceiver.type,
val receiverType = contextReceiver.label,
if (receiverTypeRef != null) { splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER),
typeResolver.resolveType(headerScope, receiverTypeRef, trace, true) index
} else {
if (function is KtFunctionLiteral) expectedFunctionType.getReceiverType() else null
}
val contextReceivers = function.contextReceivers
val contextReceiverTypes =
if (function is KtFunctionLiteral) expectedFunctionType.getContextReceiversTypes()
else contextReceivers
.mapNotNull {
val typeReference = it.typeReference() ?: return@mapNotNull null
val type = typeResolver.resolveType(headerScope, typeReference, trace, true)
ContextReceiverTypeWithLabel(type, it.labelNameAsName())
}
val valueParameterDescriptors =
createValueParameterDescriptors(function, functionDescriptor, headerScope, trace, expectedFunctionType, inferenceSession)
headerScope.freeze()
val returnType = function.typeReference?.let { typeResolver.resolveType(headerScope, it, trace, true) }
val visibility = resolveVisibilityFromModifiers(function, getDefaultVisibility(function, container))
val modality = resolveMemberModalityFromModifiers(
function, getDefaultModality(container, visibility, function.hasBody()),
trace.bindingContext, container
) )
}
val contractProvider = getContractProvider(functionDescriptor, trace, scope, dataFlowInfo, function, inferenceSession) if (languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) {
val userData = mutableMapOf<CallableDescriptor.UserDataKey<*>, Any>().apply { val labelNameToReceiverMap = HashMultimap.create<String, ReceiverParameterDescriptor>()
if (contractProvider != null) { if (receiverTypeRef != null && extensionReceiver != null) {
put(ContractProviderKey, contractProvider) receiverTypeRef.nameForReceiverLabel()?.let {
} labelNameToReceiverMap.put(it, extensionReceiver)
if (receiverType != null && expectedFunctionType.functionTypeExpected() && !expectedFunctionType.annotations.isEmpty()) {
put(DslMarkerUtils.FunctionTypeAnnotationsKey, expectedFunctionType.annotations)
} }
} }
contextReceiverDescriptors.zip(0 until contextReceivers.size).reversed()
val extensionReceiver = receiverType?.let { .forEach { (contextReceiverDescriptor, i) ->
val splitter = AnnotationSplitter(storageManager, it.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER)) contextReceivers[i].name()?.let {
DescriptorFactory.createExtensionReceiverParameterForCallable( labelNameToReceiverMap.put(it, contextReceiverDescriptor)
functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER)
)
}
val contextReceiverDescriptors = contextReceiverTypes.mapIndexedNotNull { index, contextReceiver ->
val splitter = AnnotationSplitter(storageManager, contextReceiver.type.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
DescriptorFactory.createContextReceiverParameterForCallable(
functionDescriptor,
contextReceiver.type,
contextReceiver.label,
splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER),
index
)
}
if (languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) {
val labelNameToReceiverMap = HashMultimap.create<String, ReceiverParameterDescriptor>()
if (receiverTypeRef != null && extensionReceiver != null) {
receiverTypeRef.nameForReceiverLabel()?.let {
labelNameToReceiverMap.put(it, extensionReceiver)
} }
} }
contextReceiverDescriptors.zip(0 until contextReceivers.size).reversed()
.forEach { (contextReceiverDescriptor, i) ->
contextReceivers[i].name()?.let {
labelNameToReceiverMap.put(it, contextReceiverDescriptor)
}
}
trace.record(BindingContext.DESCRIPTOR_TO_CONTEXT_RECEIVER_MAP, functionDescriptor, labelNameToReceiverMap) trace.record(BindingContext.DESCRIPTOR_TO_CONTEXT_RECEIVER_MAP, functionDescriptor, labelNameToReceiverMap)
} }
functionDescriptor.initialize( functionDescriptor.initialize(
extensionReceiver, extensionReceiver,
getDispatchReceiverParameterIfNeeded(container), getDispatchReceiverParameterIfNeeded(container),
contextReceiverDescriptors, contextReceiverDescriptors,
typeParameterDescriptors, typeParameterDescriptors,
valueParameterDescriptors, valueParameterDescriptors,
returnType, returnType,
modality, modality,
visibility, visibility,
userData.takeIf { it.isNotEmpty() } userData.takeIf { it.isNotEmpty() }
) )
functionDescriptor.isOperator = function.hasModifier(KtTokens.OPERATOR_KEYWORD) functionDescriptor.isOperator = function.hasModifier(KtTokens.OPERATOR_KEYWORD)
functionDescriptor.isInfix = function.hasModifier(KtTokens.INFIX_KEYWORD) functionDescriptor.isInfix = function.hasModifier(KtTokens.INFIX_KEYWORD)
functionDescriptor.isExternal = function.hasModifier(KtTokens.EXTERNAL_KEYWORD) functionDescriptor.isExternal = function.hasModifier(KtTokens.EXTERNAL_KEYWORD)
functionDescriptor.isInline = function.hasModifier(KtTokens.INLINE_KEYWORD) functionDescriptor.isInline = function.hasModifier(KtTokens.INLINE_KEYWORD)
functionDescriptor.isTailrec = function.hasModifier(KtTokens.TAILREC_KEYWORD) functionDescriptor.isTailrec = function.hasModifier(KtTokens.TAILREC_KEYWORD)
functionDescriptor.isSuspend = function.hasModifier(KtTokens.SUSPEND_KEYWORD) functionDescriptor.isSuspend = function.hasModifier(KtTokens.SUSPEND_KEYWORD)
functionDescriptor.isExpect = container is PackageFragmentDescriptor && function.hasExpectModifier() || functionDescriptor.isExpect = container is PackageFragmentDescriptor && function.hasExpectModifier() ||
container is ClassDescriptor && container.isExpect container is ClassDescriptor && container.isExpect
functionDescriptor.isActual = function.hasActualModifier() functionDescriptor.isActual = function.hasActualModifier()
receiverType?.let { ForceResolveUtil.forceResolveAllContents(it.annotations) } receiverType?.let { ForceResolveUtil.forceResolveAllContents(it.annotations) }
for (valueParameterDescriptor in valueParameterDescriptors) { for (valueParameterDescriptor in valueParameterDescriptors) {
ForceResolveUtil.forceResolveAllContents(valueParameterDescriptor.type.annotations) ForceResolveUtil.forceResolveAllContents(valueParameterDescriptor.type.annotations)
}
} catch (e: Exception) {
if (e is ControlFlowException) {
throw IllegalStateException("Method should be run under nonCancelableSection", e)
}
throw e
} }
} }
@@ -456,6 +444,8 @@ class FunctionDescriptorResolver(
constructorDescriptor.isActual = modifierList?.hasActualModifier() == true || constructorDescriptor.isActual = modifierList?.hasActualModifier() == true ||
// We don't require 'actual' for constructors of actual annotations // We don't require 'actual' for constructors of actual annotations
classDescriptor.kind == ClassKind.ANNOTATION_CLASS && classDescriptor.isActual classDescriptor.kind == ClassKind.ANNOTATION_CLASS && classDescriptor.isActual
if (declarationToTrace is PsiElement)
trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor)
val parameterScope = LexicalWritableScope( val parameterScope = LexicalWritableScope(
scope, scope,
constructorDescriptor, constructorDescriptor,
@@ -463,27 +453,20 @@ class FunctionDescriptorResolver(
TraceBasedLocalRedeclarationChecker(trace, overloadChecker), TraceBasedLocalRedeclarationChecker(trace, overloadChecker),
LexicalScopeKind.CONSTRUCTOR_HEADER LexicalScopeKind.CONSTRUCTOR_HEADER
) )
return computeInNonCancelableSection { val constructor = constructorDescriptor.initialize(
if (declarationToTrace is PsiElement) resolveValueParameters(
trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor) constructorDescriptor, parameterScope, valueParameters, trace, null, inferenceSession
val constructor = constructorDescriptor.initialize( ),
resolveValueParameters( resolveVisibilityFromModifiers(
constructorDescriptor, parameterScope, valueParameters, trace, null, inferenceSession modifierList,
), DescriptorUtils.getDefaultConstructorVisibility(classDescriptor, languageVersionSettings.supportsFeature(LanguageFeature.AllowSealedInheritorsInDifferentFilesOfSamePackage))
resolveVisibilityFromModifiers(
modifierList,
DescriptorUtils.getDefaultConstructorVisibility(
classDescriptor,
languageVersionSettings.supportsFeature(LanguageFeature.AllowSealedInheritorsInDifferentFilesOfSamePackage)
)
)
) )
constructor.returnType = classDescriptor.defaultType )
if (DescriptorUtils.isAnnotationClass(classDescriptor)) { constructor.returnType = classDescriptor.defaultType
CompileTimeConstantUtils.checkConstructorParametersType(valueParameters, trace) if (DescriptorUtils.isAnnotationClass(classDescriptor)) {
} CompileTimeConstantUtils.checkConstructorParametersType(valueParameters, trace)
constructor
} }
return constructor
} }
private fun resolveValueParameters( private fun resolveValueParameters(
@@ -494,67 +477,57 @@ class FunctionDescriptorResolver(
expectedParameterTypes: List<KotlinType>?, expectedParameterTypes: List<KotlinType>?,
inferenceSession: InferenceSession? inferenceSession: InferenceSession?
): List<ValueParameterDescriptor> { ): List<ValueParameterDescriptor> {
try { val result = ArrayList<ValueParameterDescriptor>()
val result = ArrayList<ValueParameterDescriptor>()
for (i in valueParameters.indices) { for (i in valueParameters.indices) {
val valueParameter = valueParameters[i] val valueParameter = valueParameters[i]
val typeReference = valueParameter.typeReference val typeReference = valueParameter.typeReference
val expectedType = expectedParameterTypes?.let { if (i < it.size) it[i] else null }?.takeUnless { TypeUtils.noExpectedType(it) } val expectedType = expectedParameterTypes?.let { if (i < it.size) it[i] else null }?.takeUnless { TypeUtils.noExpectedType(it) }
val type: KotlinType val type: KotlinType
if (typeReference != null) { if (typeReference != null) {
type = typeResolver.resolveType(parameterScope, typeReference, trace, true) type = typeResolver.resolveType(parameterScope, typeReference, trace, true)
if (expectedType != null) { if (expectedType != null) {
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(expectedType, type)) { if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(expectedType, type)) {
trace.report(EXPECTED_PARAMETER_TYPE_MISMATCH.on(valueParameter, expectedType)) trace.report(EXPECTED_PARAMETER_TYPE_MISMATCH.on(valueParameter, expectedType))
}
} }
}
} else {
type = if (isFunctionLiteral(functionDescriptor) || isFunctionExpression(functionDescriptor)) {
val containsErrorType = TypeUtils.contains(expectedType) { it.isError }
if (expectedType == null || containsErrorType) {
trace.report(CANNOT_INFER_PARAMETER_TYPE.on(valueParameter))
}
expectedType ?: TypeUtils.CANNOT_INFER_FUNCTION_PARAM_TYPE
} else { } else {
type = if (isFunctionLiteral(functionDescriptor) || isFunctionExpression(functionDescriptor)) { trace.report(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION.on(valueParameter))
val containsErrorType = TypeUtils.contains(expectedType) { it.isError } ErrorUtils.createErrorType(ErrorTypeKind.MISSED_TYPE_FOR_PARAMETER, valueParameter.nameAsSafeName.toString())
if (expectedType == null || containsErrorType) {
trace.report(CANNOT_INFER_PARAMETER_TYPE.on(valueParameter))
}
expectedType ?: TypeUtils.CANNOT_INFER_FUNCTION_PARAM_TYPE
} else {
trace.report(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION.on(valueParameter))
ErrorUtils.createErrorType(ErrorTypeKind.MISSED_TYPE_FOR_PARAMETER, valueParameter.nameAsSafeName.toString())
}
} }
}
if (functionDescriptor !is ConstructorDescriptor || !functionDescriptor.isPrimary) { if (functionDescriptor !is ConstructorDescriptor || !functionDescriptor.isPrimary) {
val isConstructor = functionDescriptor is ConstructorDescriptor val isConstructor = functionDescriptor is ConstructorDescriptor
with(modifiersChecker.withTrace(trace)) { with(modifiersChecker.withTrace(trace)) {
checkParameterHasNoValOrVar( checkParameterHasNoValOrVar(
valueParameter, valueParameter,
if (isConstructor) VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER else VAL_OR_VAR_ON_FUN_PARAMETER if (isConstructor) VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER else VAL_OR_VAR_ON_FUN_PARAMETER
) )
}
} }
val valueParameterDescriptor = descriptorResolver.resolveValueParameterDescriptor(
parameterScope, functionDescriptor, valueParameter, i, type, trace, Annotations.EMPTY, inferenceSession
)
// Do not report NAME_SHADOWING for lambda destructured parameters as they may be not fully resolved at this time
ExpressionTypingUtils.checkVariableShadowing(parameterScope, trace, valueParameterDescriptor)
parameterScope.addVariableDescriptor(valueParameterDescriptor)
result.add(valueParameterDescriptor)
} }
return result
} catch (e: Exception) { val valueParameterDescriptor = descriptorResolver.resolveValueParameterDescriptor(
if (e is ControlFlowException) { parameterScope, functionDescriptor, valueParameter, i, type, trace, Annotations.EMPTY, inferenceSession
throw IllegalStateException("Method should be run under nonCancelableSection", e) )
}
throw e // Do not report NAME_SHADOWING for lambda destructured parameters as they may be not fully resolved at this time
ExpressionTypingUtils.checkVariableShadowing(parameterScope, trace, valueParameterDescriptor)
parameterScope.addVariableDescriptor(valueParameterDescriptor)
result.add(valueParameterDescriptor)
} }
return result
} }
private data class ContextReceiverTypeWithLabel(val type: KotlinType, val label: Name?) private data class ContextReceiverTypeWithLabel(val type: KotlinType, val label: Name?)
} }
private fun <T> computeInNonCancelableSection(action: () -> T): T =
ProgressManager.getInstance().computeInNonCancelableSection<T, Exception>(action)
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.types.expressions package org.jetbrains.kotlin.types.expressions
import com.google.common.collect.Lists import com.google.common.collect.Lists
import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
@@ -210,30 +209,23 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
context: ExpressionTypingContext context: ExpressionTypingContext
): AnonymousFunctionDescriptor { ): AnonymousFunctionDescriptor {
val functionLiteral = expression.functionLiteral val functionLiteral = expression.functionLiteral
val annotations = components.annotationResolver.resolveAnnotationsWithArguments( val functionDescriptor = AnonymousFunctionDescriptor(
context.scope, context.scope.ownerDescriptor,
expression.getAnnotationEntries(), components.annotationResolver.resolveAnnotationsWithArguments(context.scope, expression.getAnnotationEntries(), context.trace),
context.trace CallableMemberDescriptor.Kind.DECLARATION, functionLiteral.toSourceElement(),
) context.expectedType.isSuspendFunctionType()
return ProgressManager.getInstance().computeInNonCancelableSection<AnonymousFunctionDescriptor, Exception> { ).let {
val functionDescriptor = AnonymousFunctionDescriptor( facade.components.typeResolutionInterceptor.interceptFunctionLiteralDescriptor(expression, context, it)
context.scope.ownerDescriptor,
annotations,
CallableMemberDescriptor.Kind.DECLARATION, functionLiteral.toSourceElement(),
context.expectedType.isSuspendFunctionType()
).let {
facade.components.typeResolutionInterceptor.interceptFunctionLiteralDescriptor(expression, context, it)
}
components.functionDescriptorResolver.initializeFunctionDescriptorAndExplicitReturnType(
context.scope.ownerDescriptor, context.scope, functionLiteral,
functionDescriptor, context.trace, context.expectedType, context.dataFlowInfo, context.inferenceSession
)
for (parameterDescriptor in functionDescriptor.valueParameters) {
ForceResolveUtil.forceResolveAllContents(parameterDescriptor.annotations)
}
BindingContextUtils.recordFunctionDeclarationToDescriptor(context.trace, functionLiteral, functionDescriptor)
functionDescriptor
} }
components.functionDescriptorResolver.initializeFunctionDescriptorAndExplicitReturnType(
context.scope.ownerDescriptor, context.scope, functionLiteral,
functionDescriptor, context.trace, context.expectedType, context.dataFlowInfo, context.inferenceSession
)
for (parameterDescriptor in functionDescriptor.valueParameters) {
ForceResolveUtil.forceResolveAllContents(parameterDescriptor.annotations)
}
BindingContextUtils.recordFunctionDeclarationToDescriptor(context.trace, functionLiteral, functionDescriptor)
return functionDescriptor
} }
private fun KotlinType.isBuiltinFunctionalType() = private fun KotlinType.isBuiltinFunctionalType() =