Esempio n. 1
0
  @NotNull
  public static <D extends CallableDescriptor, F extends D>
      List<ResolutionTask<D, F>> computePrioritizedTasks(
          @NotNull BasicResolutionContext context,
          @NotNull Name name,
          @NotNull JetReferenceExpression functionReference,
          @NotNull List<CallableDescriptorCollector<? extends D>> callableDescriptorCollectors) {
    ReceiverDescriptor explicitReceiver = context.call.getExplicitReceiver();
    final JetScope scope;
    if (explicitReceiver.exists() && explicitReceiver.getType() instanceof NamespaceType) {
      // Receiver is a namespace
      scope = explicitReceiver.getType().getMemberScope();
      explicitReceiver = NO_RECEIVER;
    } else {
      scope = context.scope;
    }
    final Predicate<ResolutionCandidate<D>> visibleStrategy =
        new Predicate<ResolutionCandidate<D>>() {
          @Override
          public boolean apply(@Nullable ResolutionCandidate<D> call) {
            if (call == null) return false;
            D candidateDescriptor = call.getDescriptor();
            if (ErrorUtils.isError(candidateDescriptor)) return true;
            return Visibilities.isVisible(candidateDescriptor, scope.getContainingDeclaration());
          }
        };

    ResolutionTaskHolder<D, F> result =
        new ResolutionTaskHolder<D, F>(functionReference, context, visibleStrategy);
    for (CallableDescriptorCollector<? extends D> callableDescriptorCollector :
        callableDescriptorCollectors) {
      doComputeTasks(scope, explicitReceiver, name, result, context, callableDescriptorCollector);
    }
    return result.getTasks();
  }
  @Override
  public void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result) {
    checkMayRead();

    super.getImplicitReceiversHierarchy(result);
    // Imported scopes come with their receivers
    // Example: class member resolution scope imports a scope of it's class object
    //          members of the class object must be able to find it as an implicit receiver
    for (JetScope scope : getImports()) {
      ReceiverDescriptor definedReceiver = scope.getImplicitReceiver();
      if (definedReceiver.exists()) {
        result.add(0, definedReceiver);
      }
    }
  }
Esempio n. 3
0
 private static <D extends CallableDescriptor> boolean setImpliedThis(
     @NotNull JetScope scope, ResolutionCandidate<D> candidate) {
   ReceiverDescriptor expectedThisObject = candidate.getDescriptor().getExpectedThisObject();
   if (!expectedThisObject.exists()) return true;
   List<ReceiverDescriptor> receivers = Lists.newArrayList();
   scope.getImplicitReceiversHierarchy(receivers);
   for (ReceiverDescriptor receiver : receivers) {
     if (JetTypeChecker.INSTANCE.isSubtypeOf(receiver.getType(), expectedThisObject.getType())) {
       // TODO : Autocasts & nullability
       candidate.setThisObject(expectedThisObject);
       return true;
     }
   }
   return false;
 }
Esempio n. 4
0
 /*
  * Checks if receiver declaration could be resolved to call expected receiver.
  */
 public static boolean checkIsExtensionCallable(
     @NotNull ReceiverDescriptor expectedReceiver, @NotNull CallableDescriptor receiverArgument) {
   JetType type = expectedReceiver.getType();
   if (checkReceiverResolution(expectedReceiver, type, receiverArgument)) return true;
   if (type.isNullable()) {
     JetType notNullableType = TypeUtils.makeNotNullable(type);
     if (checkReceiverResolution(expectedReceiver, notNullableType, receiverArgument)) return true;
   }
   return false;
 }
Esempio n. 5
0
    @Override
    public Void visitFunctionDescriptor(FunctionDescriptor descriptor, StringBuilder builder) {
      renderVisibility(descriptor.getVisibility(), builder);
      renderModality(descriptor.getModality(), builder);
      builder.append(renderKeyword("fun")).append(" ");
      if (renderTypeParameters(descriptor.getTypeParameters(), builder)) {
        builder.append(" ");
      }

      ReceiverDescriptor receiver = descriptor.getReceiverParameter();
      if (receiver.exists()) {
        builder.append(escape(renderType(receiver.getType()))).append(".");
      }

      renderName(descriptor, builder);
      renderValueParameters(descriptor, builder);
      builder.append(" : ").append(escape(renderType(descriptor.getReturnType())));
      renderWhereSuffix(descriptor, builder);
      return null;
    }
Esempio n. 6
0
 public static <D extends CallableDescriptor>
     Collection<ResolutionCandidate<D>> convertWithImpliedThis(
         JetScope scope,
         Collection<ReceiverDescriptor> receiverParameters,
         Collection<? extends D> descriptors) {
   Collection<ResolutionCandidate<D>> result = Lists.newArrayList();
   for (ReceiverDescriptor receiverParameter : receiverParameters) {
     for (D descriptor : descriptors) {
       ResolutionCandidate<D> candidate = ResolutionCandidate.create(descriptor);
       candidate.setReceiverArgument(receiverParameter);
       candidate.setExplicitReceiverKind(
           receiverParameter.exists()
               ? ExplicitReceiverKind.RECEIVER_ARGUMENT
               : ExplicitReceiverKind.NO_EXPLICIT_RECEIVER);
       if (setImpliedThis(scope, candidate)) {
         result.add(candidate);
       }
     }
   }
   if (receiverParameters.size() == 1 && !receiverParameters.iterator().next().exists()) {
     for (D descriptor : descriptors) {
       if (descriptor.getExpectedThisObject().exists()
           && !descriptor.getReceiverParameter().exists()) {
         DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
         if (descriptor instanceof ConstructorDescriptor) {
           assert containingDeclaration != null;
           containingDeclaration = containingDeclaration.getContainingDeclaration();
         }
         if (containingDeclaration != null && isClassObject(containingDeclaration)) {
           ResolutionCandidate<D> candidate = ResolutionCandidate.create(descriptor);
           candidate.setThisObject(new ClassReceiver((ClassDescriptor) containingDeclaration));
           candidate.setExplicitReceiverKind(ExplicitReceiverKind.NO_EXPLICIT_RECEIVER);
           result.add(candidate);
         }
       }
     }
   }
   return result;
 }
Esempio n. 7
0
    private String renderPropertyPrefixAndComputeTypeString(
        @NotNull StringBuilder builder,
        @Nullable Boolean isVar,
        @NotNull List<TypeParameterDescriptor> typeParameters,
        @NotNull ReceiverDescriptor receiver,
        @Nullable JetType outType) {
      String typeString = lt() + "no type>";
      if (outType != null) {
        if (isVar != null) {
          builder.append(renderKeyword(isVar ? "var" : "val")).append(" ");
        }
        typeString = renderType(outType);
      }

      renderTypeParameters(typeParameters, builder);

      if (receiver.exists()) {
        builder.append(escape(renderType(receiver.getType()))).append(".");
      }

      return typeString;
    }
Esempio n. 8
0
  private static boolean checkReceiverResolution(
      @NotNull ReceiverDescriptor expectedReceiver,
      @NotNull JetType receiverType,
      @NotNull CallableDescriptor receiverArgument) {
    ConstraintSystem constraintSystem =
        new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING);
    for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
      constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
    }

    ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
    if (expectedReceiver.exists() && receiverParameter.exists()) {
      constraintSystem.addSubtypingConstraint(
          ConstraintType.RECEIVER.assertSubtyping(receiverType, receiverParameter.getType()));
    } else if (expectedReceiver.exists() || receiverParameter.exists()) {
      // Only one of receivers exist
      return false;
    }

    ConstraintSystemSolution solution = constraintSystem.solve();
    return solution.getStatus().isSuccessful();
  }
  @Override
  public JetType visitFunctionLiteralExpression(
      JetFunctionLiteralExpression expression, ExpressionTypingContext context) {
    JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
    JetBlockExpression bodyExpression = functionLiteral.getBodyExpression();
    if (bodyExpression == null) return null;

    JetType expectedType = context.expectedType;
    boolean functionTypeExpected =
        expectedType != TypeUtils.NO_EXPECTED_TYPE
            && JetStandardClasses.isFunctionType(expectedType);

    NamedFunctionDescriptorImpl functionDescriptor =
        createFunctionDescriptor(expression, context, functionTypeExpected);

    List<JetType> parameterTypes = Lists.newArrayList();
    List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
    for (ValueParameterDescriptor valueParameter : valueParameters) {
      parameterTypes.add(valueParameter.getOutType());
    }
    ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
    JetType receiver = receiverParameter != NO_RECEIVER ? receiverParameter.getType() : null;

    JetType returnType = TypeUtils.NO_EXPECTED_TYPE;
    JetScope functionInnerScope =
        FunctionDescriptorUtil.getFunctionInnerScope(
            context.scope, functionDescriptor, context.trace);
    JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef();
    if (returnTypeRef != null) {
      returnType = context.getTypeResolver().resolveType(context.scope, returnTypeRef);
      context
          .getServices()
          .checkFunctionReturnType(
              expression,
              context
                  .replaceScope(functionInnerScope)
                  .replaceExpectedType(returnType)
                  .replaceExpectedReturnType(returnType)
                  .replaceDataFlowInfo(context.dataFlowInfo));
    } else {
      if (functionTypeExpected) {
        returnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType);
      }
      returnType =
          context
              .getServices()
              .getBlockReturnedType(
                  functionInnerScope,
                  bodyExpression,
                  CoercionStrategy.COERCION_TO_UNIT,
                  context.replaceExpectedType(returnType).replaceExpectedReturnType(returnType));
    }
    JetType safeReturnType =
        returnType == null ? ErrorUtils.createErrorType("<return type>") : returnType;
    functionDescriptor.setReturnType(safeReturnType);

    boolean hasDeclaredValueParameters = functionLiteral.getValueParameterList() != null;
    if (!hasDeclaredValueParameters && functionTypeExpected) {
      JetType expectedReturnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType);
      if (JetStandardClasses.isUnit(expectedReturnType)) {
        functionDescriptor.setReturnType(JetStandardClasses.getUnitType());
        return DataFlowUtils.checkType(
            JetStandardClasses.getFunctionType(
                Collections.<AnnotationDescriptor>emptyList(),
                receiver,
                parameterTypes,
                JetStandardClasses.getUnitType()),
            expression,
            context);
      }
    }
    return DataFlowUtils.checkType(
        JetStandardClasses.getFunctionType(
            Collections.<AnnotationDescriptor>emptyList(),
            receiver,
            parameterTypes,
            safeReturnType),
        expression,
        context);
  }
Esempio n. 10
0
  private static <D extends CallableDescriptor, F extends D> void doComputeTasks(
      @NotNull JetScope scope,
      @NotNull ReceiverDescriptor receiver,
      @NotNull Name name,
      @NotNull ResolutionTaskHolder<D, F> result,
      @NotNull BasicResolutionContext context,
      @NotNull CallableDescriptorCollector<? extends D> callableDescriptorCollector) {

    ProgressIndicatorProvider.checkCanceled();

    AutoCastServiceImpl autoCastService =
        new AutoCastServiceImpl(context.dataFlowInfo, context.trace.getBindingContext());
    List<ReceiverDescriptor> implicitReceivers = Lists.newArrayList();
    scope.getImplicitReceiversHierarchy(implicitReceivers);
    boolean hasExplicitThisObject = context.call.getThisObject().exists();
    if (hasExplicitThisObject) {
      implicitReceivers.add(context.call.getThisObject());
    }
    if (receiver.exists()) {
      List<ReceiverDescriptor> variantsForExplicitReceiver =
          autoCastService.getVariantsForReceiver(receiver);

      Collection<ResolutionCandidate<D>> extensionFunctions =
          convertWithImpliedThis(
              scope,
              variantsForExplicitReceiver,
              callableDescriptorCollector.getNonMembersByName(scope, name));
      List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
      List<ResolutionCandidate<D>> locals = Lists.newArrayList();
      //noinspection unchecked,RedundantTypeArguments
      TaskPrioritizer.<D>splitLexicallyLocalDescriptors(
          extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals);

      Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
      for (ReceiverDescriptor variant : variantsForExplicitReceiver) {
        Collection<? extends D> membersForThisVariant =
            callableDescriptorCollector.getMembersByName(variant.getType(), name);
        convertWithReceivers(
            membersForThisVariant,
            Collections.singletonList(variant),
            Collections.singletonList(NO_RECEIVER),
            members,
            hasExplicitThisObject);
      }

      result.addLocalExtensions(locals);
      result.addMembers(members);

      for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
        Collection<? extends D> memberExtensions =
            callableDescriptorCollector.getNonMembersByName(
                implicitReceiver.getType().getMemberScope(), name);
        List<ReceiverDescriptor> variantsForImplicitReceiver =
            autoCastService.getVariantsForReceiver(implicitReceiver);
        result.addNonLocalExtensions(
            convertWithReceivers(
                memberExtensions,
                variantsForImplicitReceiver,
                variantsForExplicitReceiver,
                hasExplicitThisObject));
      }

      result.addNonLocalExtensions(nonlocals);
    } else {
      Collection<ResolutionCandidate<D>> functions =
          convertWithImpliedThis(
              scope,
              Collections.singletonList(receiver),
              callableDescriptorCollector.getNonExtensionsByName(scope, name));

      List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
      List<ResolutionCandidate<D>> locals = Lists.newArrayList();
      //noinspection unchecked,RedundantTypeArguments
      TaskPrioritizer.<D>splitLexicallyLocalDescriptors(
          functions, scope.getContainingDeclaration(), locals, nonlocals);

      result.addLocalExtensions(locals);
      result.addNonLocalExtensions(nonlocals);

      for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
        doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollector);
      }
    }
  }