<commit_before>package com.intellij.codeInsight.daemon.impl.analysis;

import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.codeInsight.daemon.impl.*;
import com.intellij.codeInsight.daemon.impl.quickfix.*;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.ex.InspectionManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;

import java.util.*;

/**
 * @author cdr
 */

public abstract class GenericsHighlightUtil {
  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil");
  private static final String GENERICS_ARE_NOT_SUPPORTED = JavaErrorMessages.message("generics.are.not.supported");

  public static HighlightInfo checkInferredTypeArguments(PsiMethod genericMethod,
                                                         PsiMethodCallExpression call,
                                                         PsiSubstitutor substitutor) {
    PsiTypeParameter[] typeParameters = genericMethod.getTypeParameters();
    for (PsiTypeParameter typeParameter : typeParameters) {
      PsiType substituted = substitutor.substitute(typeParameter);
      if (substituted == null) return null;
      PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes();
      for (PsiClassType type : extendsTypes) {
        PsiType extendsType = substitutor.substituteAndFullCapture(type);
        if (!TypeConversionUtil.isAssignable(extendsType, substituted)) {
          PsiClass boundClass = extendsType instanceof PsiClassType ? ((PsiClassType)extendsType).resolve() : null;

          @NonNls String messageKey = (boundClass == null || typeParameter.isInterface() == boundClass.isInterface()
                                       ? "generics.inferred.type.for.type.parameter.is.not.within.its.bound.extend"
                                       : "generics.inferred.type.for.type.parameter.is.not.within.its.bound.implement");

          String description = JavaErrorMessages.message(
            messageKey,
            HighlightUtil.formatClass(typeParameter),
            HighlightUtil.formatType(extendsType),
            HighlightUtil.formatType(substituted)
          );

          return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, call, description);
        }
      }
    }

    return null;
  }

  public static HighlightInfo checkParameterizedReferenceTypeArguments(PsiElement resolved,
                                                                       final PsiJavaCodeReferenceElement referenceElement,
                                                                       final PsiSubstitutor substitutor) {
    if (!(resolved instanceof PsiTypeParameterListOwner)) return null;
    final PsiTypeParameterListOwner typeParameterListOwner = (PsiTypeParameterListOwner)resolved;
    return checkReferenceTypeParametersList(typeParameterListOwner, referenceElement, substitutor, true);
  }

  public static HighlightInfo checkReferenceTypeParametersList(final PsiTypeParameterListOwner typeParameterListOwner,
                                                               final PsiJavaCodeReferenceElement referenceElement,
                                                               final PsiSubstitutor substitutor, boolean registerIntentions) {
    if (referenceElement.getManager().getEffectiveLanguageLevel().compareTo(LanguageLevel.JDK_1_5) < 0) {
      final PsiReferenceParameterList parameterList = referenceElement.getParameterList();
      if (parameterList != null && parameterList.getTypeParameterElements().length > 0) {
        return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR,
                                                 parameterList,
                                                 GENERICS_ARE_NOT_SUPPORTED);
      }
    }

    final PsiTypeParameter[] typeParameters = typeParameterListOwner.getTypeParameters();
    final int targetParametersNum = typeParameters.length;
    final PsiReferenceParameterList referenceParameterList = referenceElement.getParameterList();
    final int refParametersNum = referenceParameterList == null ? 0 : referenceParameterList.getTypeParameterElements().length;
    if (targetParametersNum != refParametersNum && refParametersNum != 0) {
      final String description;
      if (targetParametersNum == 0) {
        description = JavaErrorMessages.message(
          "generics.type.or.method.does.not.have.type.parameters",
          typeParameterListOwnerCategoryDescription(typeParameterListOwner),
          typeParameterListOwnerDescription(typeParameterListOwner)
        );
      }
      else {
        description = JavaErrorMessages.message(
          "generics.wrong.number.of.type.arguments",
          new Integer(refParametersNum),
          new Integer(targetParametersNum)
        );
      }

      final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR,
                                                                            referenceParameterList,
                                                                            description);
      if (registerIntentions) {
        PsiElement parent = referenceElement.getParent();
        if (parent instanceof PsiTypeElement) {
          PsiElement variable = parent.getParent();
          if (variable instanceof PsiVariable) {
            VariableParameterizedTypeFix.registerIntentions(highlightInfo, (PsiVariable)variable, referenceElement);
          }
        }
      }
      return highlightInfo;
    }

    // bounds check
    if (targetParametersNum > 0 && refParametersNum != 0) {
      final PsiTypeElement[] referenceElements = referenceParameterList.getTypeParameterElements();
      for (int i = 0; i < typeParameters.length; i++) {
        PsiTypeParameter classParameter = typeParameters[i];
        final PsiTypeElement typeElement = referenceElements[i];
        final PsiType type = typeElement.getType();
        if (!(type instanceof PsiClassType)) continue;
        final PsiClass referenceClass = ((PsiClassType)type).resolve();
        final PsiClassType[] bounds = classParameter.getSuperTypes();
        for (PsiClassType type1 : bounds) {
          PsiType bound = substitutor.substitute(type1);
          if (!bound.equalsToText("java.lang.Object") && !TypeConversionUtil.isAssignable(bound, type)) {
            PsiClass boundClass = bound instanceof PsiClassType ? ((PsiClassType)bound).resolve() : null;

            @NonNls final String messageKey = (boundClass == null || referenceClass.isInterface() == boundClass.isInterface()
                                               ? "generics.type.parameter.is.not.within.its.bound.extend"
                                               : "generics.type.parameter.is.not.within.its.bound.implement");

            String description = JavaErrorMessages.message(messageKey,
                                                           HighlightUtil.formatClass(referenceClass),
                                                           HighlightUtil.formatType(bound));

            final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR,
                                                                                  typeElement,
                                                                                  description);
            if (bound instanceof PsiClassType) {
              QuickFixAction.registerQuickFixAction(highlightInfo, new ExtendsListFix(referenceClass, (PsiClassType)bound, true), null);
            }
            return highlightInfo;
          }
        }
      }
    }

    return null;
  }<commit_msg>cleanup<commit_after>package com.intellij.codeInsight.daemon.impl.analysis;

import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.codeInsight.daemon.impl.*;
import com.intellij.codeInsight.daemon.impl.quickfix.*;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.ex.InspectionManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;

import java.util.*;

/**
 * @author cdr
 */

public abstract class GenericsHighlightUtil {
  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil");
  private static final String GENERICS_ARE_NOT_SUPPORTED = JavaErrorMessages.message("generics.are.not.supported");

  public static HighlightInfo checkInferredTypeArguments(PsiMethod genericMethod,
                                                         PsiMethodCallExpression call,
                                                         PsiSubstitutor substitutor) {
    PsiTypeParameter[] typeParameters = genericMethod.getTypeParameters();
    for (PsiTypeParameter typeParameter : typeParameters) {
      PsiType substituted = substitutor.substitute(typeParameter);
      if (substituted == null) return null;
      PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes();
      for (PsiClassType type : extendsTypes) {
        PsiType extendsType = substitutor.substituteAndFullCapture(type);
        if (!TypeConversionUtil.isAssignable(extendsType, substituted)) {
          PsiClass boundClass = extendsType instanceof PsiClassType ? ((PsiClassType)extendsType).resolve() : null;

          @NonNls String messageKey = (boundClass == null || typeParameter.isInterface() == boundClass.isInterface()
                                       ? "generics.inferred.type.for.type.parameter.is.not.within.its.bound.extend"
                                       : "generics.inferred.type.for.type.parameter.is.not.within.its.bound.implement");

          String description = JavaErrorMessages.message(
            messageKey,
            HighlightUtil.formatClass(typeParameter),
            HighlightUtil.formatType(extendsType),
            HighlightUtil.formatType(substituted)
          );

          return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, call, description);
        }
      }
    }

    return null;
  }

  public static HighlightInfo checkParameterizedReferenceTypeArguments(PsiElement resolved,
                                                                       final PsiJavaCodeReferenceElement referenceElement,
                                                                       final PsiSubstitutor substitutor) {
    if (!(resolved instanceof PsiTypeParameterListOwner)) return null;
    final PsiTypeParameterListOwner typeParameterListOwner = (PsiTypeParameterListOwner)resolved;
    return checkReferenceTypeParametersList(typeParameterListOwner, referenceElement, substitutor, true);
  }

  public static HighlightInfo checkReferenceTypeParametersList(final PsiTypeParameterListOwner typeParameterListOwner,
                                                               final PsiJavaCodeReferenceElement referenceElement,
                                                               final PsiSubstitutor substitutor, boolean registerIntentions) {
    if (referenceElement.getManager().getEffectiveLanguageLevel().compareTo(LanguageLevel.JDK_1_5) < 0) {
      final PsiReferenceParameterList parameterList = referenceElement.getParameterList();
      if (parameterList != null && parameterList.getTypeParameterElements().length > 0) {
        return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR,
                                                 parameterList,
                                                 GENERICS_ARE_NOT_SUPPORTED);
      }
    }

    final PsiTypeParameter[] typeParameters = typeParameterListOwner.getTypeParameters();
    final int targetParametersNum = typeParameters.length;
    final PsiReferenceParameterList referenceParameterList = referenceElement.getParameterList();
    final int refParametersNum = referenceParameterList == null ? 0 : referenceParameterList.getTypeParameterElements().length;
    if (targetParametersNum != refParametersNum && refParametersNum != 0) {
      final String description;
      if (targetParametersNum == 0) {
        description = JavaErrorMessages.message(
          "generics.type.or.method.does.not.have.type.parameters",
          typeParameterListOwnerCategoryDescription(typeParameterListOwner),
          typeParameterListOwnerDescription(typeParameterListOwner)
        );
      }
      else {
        description = JavaErrorMessages.message(
          "generics.wrong.number.of.type.arguments",
          new Integer(refParametersNum),
          new Integer(targetParametersNum)
        );
      }

      final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR,
                                                                            referenceParameterList,
                                                                            description);
      if (registerIntentions) {
        PsiElement parent = referenceElement.getParent();
        if (parent instanceof PsiTypeElement) {
          PsiElement variable = parent.getParent();
          if (variable instanceof PsiVariable) {
            VariableParameterizedTypeFix.registerIntentions(highlightInfo, (PsiVariable)variable, referenceElement);
          }
        }
      }
      return highlightInfo;
    }

    // bounds check
    if (targetParametersNum > 0 && refParametersNum != 0) {
      final PsiTypeElement[] referenceElements = referenceParameterList.getTypeParameterElements();
      for (int i = 0; i < typeParameters.length; i++) {
        PsiTypeParameter classParameter = typeParameters[i];
        final PsiTypeElement typeElement = referenceElements[i];
        final PsiType type = typeElement.getType();
        if (!(type instanceof PsiClassType)) continue;
        final PsiClass referenceClass = ((PsiClassType)type).resolve();
        if (referenceClass == null) continue;
        final PsiClassType[] bounds = classParameter.getSuperTypes();
        for (PsiClassType type1 : bounds) {
          PsiType bound = substitutor.substitute(type1);
          if (!bound.equalsToText("java.lang.Object") && !TypeConversionUtil.isAssignable(bound, type)) {
            PsiClass boundClass = bound instanceof PsiClassType ? ((PsiClassType)bound).resolve() : null;

            @NonNls final String messageKey = (boundClass == null || referenceClass.isInterface() == boundClass.isInterface()
                                               ? "generics.type.parameter.is.not.within.its.bound.extend"
                                               : "generics.type.parameter.is.not.within.its.bound.implement");

            String description = JavaErrorMessages.message(messageKey,
                                                           HighlightUtil.formatClass(referenceClass),
                                                           HighlightUtil.formatType(bound));

            final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR,
                                                                                  typeElement,
                                                                                  description);
            if (bound instanceof PsiClassType) {
              QuickFixAction.registerQuickFixAction(highlightInfo, new ExtendsListFix(referenceClass, (PsiClassType)bound, true), null);
            }
            return highlightInfo;
          }
        }
      }
    }

    return null;
  }
{'fraction_non_alphanumeric': 0.07863073035735772, 'fraction_numerical': 0.0014438695704488027, 'mean_word_length': 2.3718052738336715, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 84, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6082549', 'n_tokens_mistral': 3922, 'n_tokens_neox': 3780, 'n_words': 698}