Exemplo n.º 1
0
  @Nullable
  public static KtExpression getParentCallIfPresent(@NotNull KtExpression expression) {
    PsiElement parent = expression.getParent();
    while (parent != null) {
      if (parent instanceof KtBinaryExpression
          || parent instanceof KtUnaryExpression
          || parent instanceof KtLabeledExpression
          || parent instanceof KtDotQualifiedExpression
          || parent instanceof KtCallExpression
          || parent instanceof KtArrayAccessExpression
          || parent instanceof KtDestructuringDeclaration) {

        if (parent instanceof KtLabeledExpression) {
          parent = parent.getParent();
          continue;
        }

        // check that it's in inlineable call would be in resolve call of parent
        return (KtExpression) parent;
      } else if (parent instanceof KtParenthesizedExpression
          || parent instanceof KtBinaryExpressionWithTypeRHS) {
        parent = parent.getParent();
      } else if (parent instanceof KtValueArgument || parent instanceof KtValueArgumentList) {
        parent = parent.getParent();
      } else if (parent instanceof KtLambdaExpression || parent instanceof KtAnnotatedExpression) {
        parent = parent.getParent();
      } else {
        return null;
      }
    }
    return null;
  }
  /**
   * Visits block statements propagating data flow information from the first to the last.
   * Determines block returned type and data flow information at the end of the block AND at the
   * nearest jump point from the block beginning.
   */
  /*package*/ KotlinTypeInfo getBlockReturnedTypeWithWritableScope(
      @NotNull LexicalWritableScope scope,
      @NotNull List<? extends KtElement> block,
      @NotNull CoercionStrategy coercionStrategyForLastExpression,
      @NotNull ExpressionTypingContext context) {
    if (block.isEmpty()) {
      return TypeInfoFactoryKt.createTypeInfo(
          expressionTypingComponents.builtIns.getUnitType(), context);
    }

    ExpressionTypingInternals blockLevelVisitor =
        new ExpressionTypingVisitorDispatcher.ForBlock(
            expressionTypingComponents, annotationChecker, scope);
    ExpressionTypingContext newContext =
        context.replaceScope(scope).replaceExpectedType(NO_EXPECTED_TYPE);

    KotlinTypeInfo result = TypeInfoFactoryKt.noTypeInfo(context);
    // Jump point data flow info
    DataFlowInfo beforeJumpInfo = newContext.dataFlowInfo;
    boolean jumpOutPossible = false;
    for (Iterator<? extends KtElement> iterator = block.iterator(); iterator.hasNext(); ) {
      KtElement statement = iterator.next();
      if (!(statement instanceof KtExpression)) {
        continue;
      }
      KtExpression statementExpression = (KtExpression) statement;
      if (!iterator.hasNext()) {
        result =
            getTypeOfLastExpressionInBlock(
                statementExpression,
                newContext.replaceExpectedType(context.expectedType),
                coercionStrategyForLastExpression,
                blockLevelVisitor);
        if (result.getType() != null
            && statementExpression.getParent() instanceof KtBlockExpression) {
          DataFlowValue lastExpressionValue =
              DataFlowValueFactory.createDataFlowValue(
                  statementExpression, result.getType(), context);
          DataFlowValue blockExpressionValue =
              DataFlowValueFactory.createDataFlowValue(
                  (KtBlockExpression) statementExpression.getParent(), result.getType(), context);
          result =
              result.replaceDataFlowInfo(
                  result.getDataFlowInfo().assign(blockExpressionValue, lastExpressionValue));
        }
      } else {
        result =
            blockLevelVisitor.getTypeInfo(
                statementExpression,
                newContext.replaceContextDependency(ContextDependency.INDEPENDENT),
                true);
      }

      DataFlowInfo newDataFlowInfo = result.getDataFlowInfo();
      // If jump is not possible, we take new data flow info before jump
      if (!jumpOutPossible) {
        beforeJumpInfo = result.getJumpFlowInfo();
        jumpOutPossible = result.getJumpOutPossible();
      }
      if (newDataFlowInfo != context.dataFlowInfo) {
        newContext = newContext.replaceDataFlowInfo(newDataFlowInfo);
        // We take current data flow info if jump there is not possible
      }
      blockLevelVisitor =
          new ExpressionTypingVisitorDispatcher.ForBlock(
              expressionTypingComponents, annotationChecker, scope);
    }
    return result.replaceJumpOutPossible(jumpOutPossible).replaceJumpFlowInfo(beforeJumpInfo);
  }
Exemplo n.º 3
0
 public static boolean isLHSOfDot(@NotNull KtExpression expression) {
   PsiElement parent = expression.getParent();
   if (!(parent instanceof KtQualifiedExpression)) return false;
   KtQualifiedExpression qualifiedParent = (KtQualifiedExpression) parent;
   return qualifiedParent.getReceiverExpression() == expression || isLHSOfDot(qualifiedParent);
 }