@NotNull
  public KotlinType getBodyExpressionType(
      @NotNull BindingTrace trace,
      @NotNull LexicalScope outerScope,
      @NotNull DataFlowInfo dataFlowInfo,
      @NotNull KtDeclarationWithBody function,
      @NotNull FunctionDescriptor functionDescriptor) {
    KtExpression bodyExpression = function.getBodyExpression();
    assert bodyExpression != null;
    LexicalScope functionInnerScope =
        FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace);

    ExpressionTypingContext context =
        ExpressionTypingContext.newContext(
            trace, functionInnerScope, dataFlowInfo, NO_EXPECTED_TYPE);
    KotlinTypeInfo typeInfo =
        expressionTypingFacade.getTypeInfo(bodyExpression, context, function.hasBlockBody());

    KotlinType type = typeInfo.getType();
    if (type != null) {
      return type;
    } else {
      return ErrorUtils.createErrorType("Error function type");
    }
  }
Пример #2
0
  public void resolveFunctionBody(
      @NotNull DataFlowInfo outerDataFlowInfo,
      @NotNull BindingTrace trace,
      @NotNull JetDeclarationWithBody function,
      @NotNull FunctionDescriptor functionDescriptor,
      @NotNull LexicalScope scope,
      @Nullable Function1<LexicalScope, DataFlowInfo> beforeBlockBody,
      @NotNull CallChecker callChecker) {
    LexicalScope innerScope =
        FunctionDescriptorUtil.getFunctionInnerScope(scope, functionDescriptor, trace);
    List<JetParameter> valueParameters = function.getValueParameters();
    List<ValueParameterDescriptor> valueParameterDescriptors =
        functionDescriptor.getValueParameters();

    valueParameterResolver.resolveValueParameters(
        valueParameters,
        valueParameterDescriptors,
        ExpressionTypingContext.newContext(
            trace, innerScope, outerDataFlowInfo, NO_EXPECTED_TYPE, callChecker));

    // Synthetic "field" creation
    if (functionDescriptor instanceof PropertyAccessorDescriptor) {
      PropertyAccessorDescriptor accessorDescriptor =
          (PropertyAccessorDescriptor) functionDescriptor;
      JetProperty property = (JetProperty) function.getParent();
      final SyntheticFieldDescriptor fieldDescriptor =
          new SyntheticFieldDescriptor(accessorDescriptor, property);
      innerScope =
          new LexicalScopeImpl(
              innerScope,
              functionDescriptor,
              true,
              functionDescriptor.getExtensionReceiverParameter(),
              "Accessor inner scope with synthetic field",
              RedeclarationHandler.DO_NOTHING,
              new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
                @Override
                public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
                  handler.addVariableOrClassDescriptor(fieldDescriptor);
                  return Unit.INSTANCE$;
                }
              });
      // Check parameter name shadowing
      for (JetParameter parameter : function.getValueParameters()) {
        if (SyntheticFieldDescriptor.NAME.equals(parameter.getNameAsName())) {
          trace.report(Errors.ACCESSOR_PARAMETER_NAME_SHADOWING.on(parameter));
        }
      }
    }

    DataFlowInfo dataFlowInfo = null;

    if (beforeBlockBody != null) {
      dataFlowInfo = beforeBlockBody.invoke(innerScope);
    }

    if (function.hasBody()) {
      expressionTypingServices.checkFunctionReturnType(
          innerScope,
          function,
          functionDescriptor,
          dataFlowInfo != null ? dataFlowInfo : outerDataFlowInfo,
          null,
          trace);
    }

    assert functionDescriptor.getReturnType() != null;
  }
Пример #3
0
  public void resolveDelegationSpecifierList(
      @NotNull final DataFlowInfo outerDataFlowInfo,
      @NotNull JetClassOrObject jetClass,
      @NotNull final ClassDescriptor descriptor,
      @Nullable final ConstructorDescriptor primaryConstructor,
      @NotNull LexicalScope scopeForSupertypeResolution,
      @NotNull final LexicalScope scopeForMemberResolution) {
    final LexicalScope scopeForConstructor =
        primaryConstructor == null
            ? null
            : FunctionDescriptorUtil.getFunctionInnerScope(
                scopeForSupertypeResolution, primaryConstructor, trace);
    final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow

    final Map<JetTypeReference, JetType> supertypes = Maps.newLinkedHashMap();
    final ResolvedCall<?>[] primaryConstructorDelegationCall = new ResolvedCall[1];
    JetVisitorVoid visitor =
        new JetVisitorVoid() {
          private void recordSupertype(JetTypeReference typeReference, JetType supertype) {
            if (supertype == null) return;
            supertypes.put(typeReference, supertype);
          }

          @Override
          public void visitDelegationByExpressionSpecifier(
              @NotNull JetDelegatorByExpressionSpecifier specifier) {
            if (descriptor.getKind() == ClassKind.INTERFACE) {
              trace.report(DELEGATION_IN_TRAIT.on(specifier));
            }
            JetType 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_TRAIT.on(specifier.getTypeReference()));
                }
              }
            }
            JetExpression delegateExpression = specifier.getDelegateExpression();
            if (delegateExpression != null) {
              LexicalScope scope =
                  scopeForConstructor == null ? scopeForMemberResolution : scopeForConstructor;
              JetType 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 visitDelegationToSuperCallSpecifier(@NotNull JetDelegatorToSuperCall call) {
            JetValueArgumentList valueArgumentList = call.getValueArgumentList();
            PsiElement elementToMark = valueArgumentList == null ? call : valueArgumentList;
            if (descriptor.getKind() == ClassKind.INTERFACE) {
              trace.report(SUPERTYPE_INITIALIZED_IN_TRAIT.on(elementToMark));
            }
            JetTypeReference 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.makeCall(ReceiverValue.NO_RECEIVER, null, call),
                    NO_EXPECTED_TYPE,
                    outerDataFlowInfo,
                    false);
            if (results.isSuccess()) {
              JetType 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(),
                  TypeInfoFactoryPackage.noTypeInfo(
                      results.getResultingCall().getDataFlowInfoForArguments().getResultInfo()));
            } else {
              recordSupertype(
                  typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
            }
          }

          @Override
          public void visitDelegationToSuperClassSpecifier(
              @NotNull JetDelegatorToSuperClass specifier) {
            JetTypeReference typeReference = specifier.getTypeReference();
            JetType 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()
                && !ErrorUtils.isError(superClass)) {
              trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier));
            }
          }

          @Override
          public void visitJetElement(@NotNull JetElement element) {
            throw new UnsupportedOperationException(element.getText() + " : " + element);
          }
        };

    for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
      delegationSpecifier.accept(visitor);
    }

    if (DescriptorUtils.isAnnotationClass(descriptor)
        && jetClass.getDelegationSpecifierList() != null) {
      trace.report(SUPERTYPES_FOR_ANNOTATION_CLASS.on(jetClass.getDelegationSpecifierList()));
    }

    if (primaryConstructorDelegationCall[0] != null && primaryConstructor != null) {
      recordConstructorDelegationCall(
          trace, primaryConstructor, primaryConstructorDelegationCall[0]);
    }

    checkSupertypeList(descriptor, supertypes, jetClass);
  }