<commit_before>/*
 * Copyright 2000-2013 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.psi.impl.source.resolve.graphInference;

import com.intellij.psi.*;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * User: anna
 */
public class PsiPolyExpressionUtil {
  public static boolean hasStandaloneForm(PsiExpression expression) {
    if (expression instanceof PsiLambdaExpression ||
        expression instanceof PsiMethodReferenceExpression ||
        expression instanceof PsiParenthesizedExpression ||
        expression instanceof PsiConditionalExpression ||
        expression instanceof PsiCallExpression) {
      return false;
    }
    return true;
  }

  public static boolean isPolyExpression(PsiExpression expression) {
    if (expression instanceof PsiLambdaExpression || expression instanceof PsiMethodReferenceExpression) {
      return true;
    } 
    else if (expression instanceof PsiParenthesizedExpression) {
      return isPolyExpression(((PsiParenthesizedExpression)expression).getExpression());
    }
    else if (expression instanceof PsiNewExpression) {
      final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)expression).getClassReference();
      if (classReference != null) {
        final PsiReferenceParameterList parameterList = classReference.getParameterList();
        if (parameterList != null) {
          final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
          if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) {
            return isAssignmentOrInvocationContext(expression.getParent());
          }
        }
      }
    } else if (expression instanceof PsiMethodCallExpression) {
      if (isAssignmentOrInvocationContext(expression.getParent()) && ((PsiMethodCallExpression)expression).getTypeArguments().length == 0) {
        final PsiMethod method = ((PsiMethodCallExpression)expression).resolveMethod();
        if (method != null) {
          final Set<PsiTypeParameter> typeParameters = new HashSet<PsiTypeParameter>(Arrays.asList(method.getTypeParameters()));
          if (typeParameters.size() > 0) {
            final PsiType returnType = method.getReturnType();
            if (returnType != null) {
              return returnTypeMentionsTypeParameters(typeParameters, returnType);
            }
          }
        }
      }
    }
    else if (expression instanceof PsiConditionalExpression) {
      final ConditionalKind conditionalKind = isBooleanOrNumeric(expression);
      if (conditionalKind == null) {
        return isAssignmentOrInvocationContext(expression.getParent());
      }
    }
    return false;
  }

  public static PsiType getTargetType(@NotNull PsiCallExpression expression) {
    return PsiTypesUtil.getExpectedTypeByParent(expression);
  }
  
  private static Boolean returnTypeMentionsTypeParameters(final Set<PsiTypeParameter> typeParameters, PsiType returnType) {
    return returnType.accept(new PsiTypeVisitor<Boolean>() {
      @Nullable
      @Override
      public Boolean visitType(PsiType type) {
        return false;
      }

      @Nullable
      @Override
      public Boolean visitClassType(PsiClassType classType) {
        for (PsiType type : classType.getParameters()) {
          if (type.accept(this)) return true;
        }
        final PsiClass psiClass = classType.resolve();
        return psiClass instanceof PsiTypeParameter && typeParameters.contains(psiClass);
      }

      @Nullable
      @Override
      public Boolean visitArrayType(PsiArrayType arrayType) {
        return arrayType.getComponentType().accept(this);
      }
    });<commit_msg>new inference: wildcard bounds could mention type vars<commit_after>/*
 * Copyright 2000-2013 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.psi.impl.source.resolve.graphInference;

import com.intellij.psi.*;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * User: anna
 */
public class PsiPolyExpressionUtil {
  public static boolean hasStandaloneForm(PsiExpression expression) {
    if (expression instanceof PsiLambdaExpression ||
        expression instanceof PsiMethodReferenceExpression ||
        expression instanceof PsiParenthesizedExpression ||
        expression instanceof PsiConditionalExpression ||
        expression instanceof PsiCallExpression) {
      return false;
    }
    return true;
  }

  public static boolean isPolyExpression(PsiExpression expression) {
    if (expression instanceof PsiLambdaExpression || expression instanceof PsiMethodReferenceExpression) {
      return true;
    } 
    else if (expression instanceof PsiParenthesizedExpression) {
      return isPolyExpression(((PsiParenthesizedExpression)expression).getExpression());
    }
    else if (expression instanceof PsiNewExpression) {
      final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)expression).getClassReference();
      if (classReference != null) {
        final PsiReferenceParameterList parameterList = classReference.getParameterList();
        if (parameterList != null) {
          final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
          if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) {
            return isAssignmentOrInvocationContext(expression.getParent());
          }
        }
      }
    } else if (expression instanceof PsiMethodCallExpression) {
      if (isAssignmentOrInvocationContext(expression.getParent()) && ((PsiMethodCallExpression)expression).getTypeArguments().length == 0) {
        final PsiMethod method = ((PsiMethodCallExpression)expression).resolveMethod();
        if (method != null) {
          final Set<PsiTypeParameter> typeParameters = new HashSet<PsiTypeParameter>(Arrays.asList(method.getTypeParameters()));
          if (typeParameters.size() > 0) {
            final PsiType returnType = method.getReturnType();
            if (returnType != null) {
              return returnTypeMentionsTypeParameters(typeParameters, returnType);
            }
          }
        }
      }
    }
    else if (expression instanceof PsiConditionalExpression) {
      final ConditionalKind conditionalKind = isBooleanOrNumeric(expression);
      if (conditionalKind == null) {
        return isAssignmentOrInvocationContext(expression.getParent());
      }
    }
    return false;
  }

  public static PsiType getTargetType(@NotNull PsiCallExpression expression) {
    return PsiTypesUtil.getExpectedTypeByParent(expression);
  }
  
  private static Boolean returnTypeMentionsTypeParameters(final Set<PsiTypeParameter> typeParameters, PsiType returnType) {
    return returnType.accept(new PsiTypeVisitor<Boolean>() {
      @Nullable
      @Override
      public Boolean visitType(PsiType type) {
        return false;
      }

      @Nullable
      @Override
      public Boolean visitWildcardType(PsiWildcardType wildcardType) {
        final PsiType bound = wildcardType.getBound();
        if (bound != null) {
          return bound.accept(this);
        }
        return false;
      }

      @Nullable
      @Override
      public Boolean visitClassType(PsiClassType classType) {
        for (PsiType type : classType.getParameters()) {
          if (type.accept(this)) return true;
        }
        final PsiClass psiClass = classType.resolve();
        return psiClass instanceof PsiTypeParameter && typeParameters.contains(psiClass);
      }

      @Nullable
      @Override
      public Boolean visitArrayType(PsiArrayType arrayType) {
        return arrayType.getComponentType().accept(this);
      }
    });
{'fraction_non_alphanumeric': 0.0835896309314587, 'fraction_numerical': 0.0035149384885764497, 'mean_word_length': 3.4985177865612647, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7064997', 'n_tokens_mistral': 2298, 'n_tokens_neox': 2273, 'n_words': 606}