All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intellij.codeInspection.dataFlow.StringExpressionHelper Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition java-analysis-impl library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.codeInspection.dataFlow;

import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.CommonProcessors;
import com.intellij.util.containers.hash.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Set;

public class StringExpressionHelper {

  @Nullable
  public static Pair evaluateExpression(@NotNull PsiElement expression) {
    return evaluateExpression(expression, new HashSet());
  }

  @Nullable
  public static Pair evaluateExpression(@NotNull PsiElement expression, @NotNull Collection visited) {
    visited.add(expression);

    if (expression instanceof PsiLiteralExpression) {
      return evaluatePsiLiteralExpression(expression);
    }

    if (expression instanceof PsiReferenceExpression) {
      PsiElement resolve = ((PsiReferenceExpression)expression).resolve();
      if (resolve instanceof PsiVariable) {
        PsiExpression initializer = ((PsiVariable)resolve).getInitializer();
        if (initializer != null) {
          Pair expr = evaluateExpression(initializer, visited);
          if (expr != null) return expr;
        }
      }
    }

    if (expression instanceof PsiMethodCallExpression) {
      final PsiElement element = ((PsiMethodCallExpression)expression).getMethodExpression().resolve();
      if (element instanceof PsiMethod) {
        PsiCodeBlock body = ((PsiMethod)element).getBody();
        if (body != null) {
          final Set returns = new com.intellij.util.containers.HashSet();

          body.accept(new JavaRecursiveElementVisitor() {
            public void visitClass(PsiClass aClass) {}

            public void visitLambdaExpression(PsiLambdaExpression expression) {}

            @Override
            public void visitReturnStatement(PsiReturnStatement statement) {
              PsiExpression returnValue = statement.getReturnValue();
              if (returnValue != null) {
                returns.add(returnValue);
              }
            }
          });

          for (PsiExpression psiExpression : returns) {
            Pair pair = evaluateExpression(psiExpression, visited);
            if (pair != null) {
              return pair;
            }
          }
        }

        return evaluateExpression(element, visited);
      }
      return null;
    }

    Pair constantExpression = evaluateConstantExpression(expression);
    if (constantExpression != null) {
      return constantExpression;
    }

    if (expression instanceof PsiBinaryExpression) {
      // a="a"; b="b"  return a+b;
      PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression;
      return evaluatePolyadicExpressions(expression, visited, binaryExpression.getLOperand(), binaryExpression.getROperand());
    }
    if (expression instanceof PsiPolyadicExpression) {
      // a="a"; b="b"; c="c"  return a+b+c;
      return evaluatePolyadicExpressions(expression, visited, ((PsiPolyadicExpression)expression).getOperands());
    }


    Collection elements = DfaUtil.getPossibleInitializationElements(expression);
    for (PsiElement element : elements) {
      if (!visited.contains(element)) {
        Pair expr = evaluateExpression(element);
        if (expr != null) return expr;
      }
    }

    return null;
  }

  @Nullable
  private static Pair evaluatePolyadicExpressions(@NotNull PsiElement expression,
                                                                      @NotNull Collection visited,
                                                                      @NotNull PsiExpression... operands) {
    StringBuilder sb = new StringBuilder();
    for (PsiExpression operand : operands) {
      Pair pair = evaluateExpression(operand, visited);
      if (pair == null) return null;
      sb.append(pair.second);
    }
    return Pair.create(expression, sb.toString());
  }

  @Nullable
  public static Pair evaluatePsiLiteralExpression(@NotNull PsiElement expression) {
    return Pair.create(expression, ElementManipulators.getValueText(expression));
  }

  @Nullable
  public static Pair evaluateConstantExpression(@NotNull PsiElement expression) {
    PsiConstantEvaluationHelper helper = JavaPsiFacade.getInstance(expression.getProject()).getConstantEvaluationHelper();
    Object result = helper.computeConstantExpression(expression);
    if (result instanceof String) {
      return Pair.create(expression, (String)result);
    }
    return null;
  }

  @NotNull
  public static Set> searchStringExpressions(@NotNull final PsiMethod psiMethod,
                                                                      @NotNull SearchScope searchScope,
                                                                      int expNum) {
    Set> pairs = new com.intellij.util.containers.HashSet>();
    for (PsiMethodCallExpression methodCallExpression : searchMethodCalls(psiMethod, searchScope)) {
      final PsiExpression[] expressions = methodCallExpression.getArgumentList().getExpressions();
      if (expressions.length > expNum) {
        final PsiExpression expression = expressions[expNum];
        Pair pair = evaluateExpression(expression);
        if (pair != null) {
          pairs.add(pair);
        }
      }
    }

    return pairs;
  }

  @NotNull
  public static Set searchMethodCalls(@NotNull final PsiMethod psiMethod, @NotNull SearchScope searchScope) {
    final Set callExpressions = new com.intellij.util.containers.HashSet();
    final CommonProcessors.CollectUniquesProcessor consumer = new CommonProcessors.CollectUniquesProcessor();

    MethodReferencesSearch.search(psiMethod, searchScope, true).forEach(consumer);

    for (PsiReference psiReference : consumer.getResults()) {
      final PsiMethodCallExpression methodCallExpression =
        PsiTreeUtil.getParentOfType(psiReference.getElement(), PsiMethodCallExpression.class);

      if (methodCallExpression != null) {
        callExpressions.add(methodCallExpression);
      }
    }


    return callExpressions;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy