use of org.jetbrains.kotlin.types.expressions.ExpressionTypingServices in project kotlin by JetBrains.
the class BodyResolver method resolveSuperTypeEntryList.
public void resolveSuperTypeEntryList(@NotNull final DataFlowInfo outerDataFlowInfo, @NotNull KtClassOrObject ktClass, @NotNull final ClassDescriptor descriptor, @Nullable final ConstructorDescriptor primaryConstructor, @NotNull LexicalScope scopeForConstructorResolution, @NotNull final LexicalScope scopeForMemberResolution) {
final LexicalScope scopeForConstructor = primaryConstructor == null ? null : FunctionDescriptorUtil.getFunctionInnerScope(scopeForConstructorResolution, primaryConstructor, trace, overloadChecker);
// TODO : flow
final ExpressionTypingServices typeInferrer = expressionTypingServices;
final Map<KtTypeReference, KotlinType> supertypes = Maps.newLinkedHashMap();
final ResolvedCall<?>[] primaryConstructorDelegationCall = new ResolvedCall[1];
KtVisitorVoid visitor = new KtVisitorVoid() {
private void recordSupertype(KtTypeReference typeReference, KotlinType supertype) {
if (supertype == null)
return;
supertypes.put(typeReference, supertype);
}
@Override
public void visitDelegatedSuperTypeEntry(@NotNull KtDelegatedSuperTypeEntry specifier) {
if (descriptor.getKind() == ClassKind.INTERFACE) {
trace.report(DELEGATION_IN_INTERFACE.on(specifier));
}
KotlinType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
recordSupertype(specifier.getTypeReference(), supertype);
if (supertype != null) {
DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor();
if (declarationDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
if (classDescriptor.getKind() != ClassKind.INTERFACE) {
trace.report(DELEGATION_NOT_TO_INTERFACE.on(specifier.getTypeReference()));
}
}
}
KtExpression delegateExpression = specifier.getDelegateExpression();
if (delegateExpression != null) {
LexicalScope scope = scopeForConstructor == null ? scopeForMemberResolution : scopeForConstructor;
KotlinType expectedType = supertype != null ? supertype : NO_EXPECTED_TYPE;
typeInferrer.getType(scope, delegateExpression, expectedType, outerDataFlowInfo, trace);
}
if (primaryConstructor == null) {
trace.report(UNSUPPORTED.on(specifier, "Delegation without primary constructor is not supported"));
}
}
@Override
public void visitSuperTypeCallEntry(@NotNull KtSuperTypeCallEntry call) {
KtValueArgumentList valueArgumentList = call.getValueArgumentList();
PsiElement elementToMark = valueArgumentList == null ? call : valueArgumentList;
if (descriptor.getKind() == ClassKind.INTERFACE) {
trace.report(SUPERTYPE_INITIALIZED_IN_INTERFACE.on(elementToMark));
}
KtTypeReference typeReference = call.getTypeReference();
if (typeReference == null)
return;
if (primaryConstructor == null) {
if (descriptor.getKind() != ClassKind.INTERFACE) {
trace.report(SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR.on(call));
}
recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
return;
}
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(trace, scopeForConstructor, CallMaker.makeConstructorCallWithoutTypeArguments(call), NO_EXPECTED_TYPE, outerDataFlowInfo, false);
if (results.isSuccess()) {
KotlinType supertype = results.getResultingDescriptor().getReturnType();
recordSupertype(typeReference, supertype);
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
if (classDescriptor != null) {
// allow only one delegating constructor
if (primaryConstructorDelegationCall[0] == null) {
primaryConstructorDelegationCall[0] = results.getResultingCall();
} else {
primaryConstructorDelegationCall[0] = null;
}
}
// Recording type info for callee to use later in JetObjectLiteralExpression
trace.record(PROCESSED, call.getCalleeExpression(), true);
trace.record(EXPRESSION_TYPE_INFO, call.getCalleeExpression(), TypeInfoFactoryKt.noTypeInfo(results.getResultingCall().getDataFlowInfoForArguments().getResultInfo()));
} else {
recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
}
}
@Override
public void visitSuperTypeEntry(@NotNull KtSuperTypeEntry specifier) {
KtTypeReference typeReference = specifier.getTypeReference();
KotlinType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference);
recordSupertype(typeReference, supertype);
if (supertype == null)
return;
ClassDescriptor superClass = TypeUtils.getClassDescriptor(supertype);
if (superClass == null)
return;
if (superClass.getKind().isSingleton()) {
// A "singleton in supertype" diagnostic will be reported later
return;
}
if (descriptor.getKind() != ClassKind.INTERFACE && descriptor.getUnsubstitutedPrimaryConstructor() != null && superClass.getKind() != ClassKind.INTERFACE && !superClass.getConstructors().isEmpty() && !descriptor.isHeader() && !DescriptorUtils.isEffectivelyExternal(descriptor) && !ErrorUtils.isError(superClass)) {
trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier));
}
}
@Override
public void visitKtElement(@NotNull KtElement element) {
throw new UnsupportedOperationException(element.getText() + " : " + element);
}
};
if (ktClass instanceof KtEnumEntry && DescriptorUtils.isEnumEntry(descriptor) && ktClass.getSuperTypeListEntries().isEmpty()) {
assert scopeForConstructor != null : "Scope for enum class constructor should be non-null: " + descriptor;
resolveConstructorCallForEnumEntryWithoutInitializer((KtEnumEntry) ktClass, descriptor, scopeForConstructor, outerDataFlowInfo);
}
for (KtSuperTypeListEntry delegationSpecifier : ktClass.getSuperTypeListEntries()) {
delegationSpecifier.accept(visitor);
}
if (DescriptorUtils.isAnnotationClass(descriptor) && ktClass.getSuperTypeList() != null) {
trace.report(SUPERTYPES_FOR_ANNOTATION_CLASS.on(ktClass.getSuperTypeList()));
}
if (primaryConstructorDelegationCall[0] != null && primaryConstructor != null) {
recordConstructorDelegationCall(trace, primaryConstructor, primaryConstructorDelegationCall[0]);
}
checkSupertypeList(descriptor, supertypes, ktClass);
}
Aggregations