public static boolean proveArrayTypeDistinct(Project project, PsiArrayType type, PsiType bound) {
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
    final GlobalSearchScope searchScope = GlobalSearchScope.allScope(project);
    final Set<PsiClass> possibleClasses = new HashSet<PsiClass>();
    possibleClasses.add(facade.findClass(CommonClassNames.JAVA_IO_SERIALIZABLE, searchScope));
    possibleClasses.add(facade.findClass(CommonClassNames.JAVA_LANG_CLONEABLE, searchScope));
    possibleClasses.add(facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, searchScope));

    if (type.getArrayDimensions() == bound.getArrayDimensions()) {
      final PsiType componentType = type.getComponentType();
      final PsiType boundComponentType = ((PsiArrayType) bound).getComponentType();
      if (boundComponentType instanceof PsiClassType && componentType instanceof PsiClassType) {
        return proveExtendsBoundsDistinct(
            boundComponentType,
            componentType,
            ((PsiClassType) boundComponentType).resolve(),
            ((PsiClassType) componentType).resolve());
      } else {
        return !bound.equals(type);
      }
    } else if (bound.getArrayDimensions() + 1 == type.getArrayDimensions()
        && bound.getDeepComponentType() instanceof PsiClassType) {
      return !possibleClasses.contains(((PsiClassType) bound.getDeepComponentType()).resolve());
    } else if (bound.getArrayDimensions() == type.getArrayDimensions() + 1
        && type.getDeepComponentType() instanceof PsiClassType) {
      return !possibleClasses.contains(((PsiClassType) type.getDeepComponentType()).resolve());
    } else if (bound instanceof PsiClassType) {
      return !possibleClasses.contains(((PsiClassType) bound).resolve());
    } else if (bound instanceof PsiWildcardType) {
      final PsiType boundBound = ((PsiWildcardType) bound).getBound();
      return boundBound != null && !boundBound.equals(type);
    }
    return true;
  }
  private int substituteToTypeParameters(
      PsiTypeElement typeElement,
      PsiTypeElement inplaceTypeElement,
      PsiType[] paramVals,
      PsiTypeParameter[] params,
      TemplateBuilder builder,
      PsiSubstitutor rawingSubstitutor,
      boolean toplevel) {
    PsiType type = inplaceTypeElement.getType();
    List<PsiType> types = new ArrayList<>();
    for (int i = 0; i < paramVals.length; i++) {
      PsiType val = paramVals[i];
      if (val == null) return SUBSTITUTED_NONE;
      if (type.equals(val)) {
        types.add(myFactory.createType(params[i]));
      }
    }

    if (!types.isEmpty()) {
      Project project = typeElement.getProject();
      PsiType substituted = rawingSubstitutor.substitute(type);
      if (!CommonClassNames.JAVA_LANG_OBJECT.equals(substituted.getCanonicalText())
          && (toplevel || substituted.equals(type))) {
        types.add(substituted);
      }

      builder.replaceElement(
          typeElement,
          new TypeExpression(project, types.toArray(PsiType.createArray(types.size()))));
      return toplevel ? SUBSTITUTED_IN_REF : SUBSTITUTED_IN_PARAMETERS;
    }

    boolean substituted = false;
    PsiJavaCodeReferenceElement ref = typeElement.getInnermostComponentReferenceElement();
    PsiJavaCodeReferenceElement inplaceRef =
        inplaceTypeElement.getInnermostComponentReferenceElement();
    if (ref != null) {
      LOG.assertTrue(inplaceRef != null);
      PsiTypeElement[] innerTypeElements = ref.getParameterList().getTypeParameterElements();
      PsiTypeElement[] inplaceInnerTypeElements =
          inplaceRef.getParameterList().getTypeParameterElements();
      for (int i = 0; i < innerTypeElements.length; i++) {
        substituted |=
            substituteToTypeParameters(
                    innerTypeElements[i],
                    inplaceInnerTypeElements[i],
                    paramVals,
                    params,
                    builder,
                    rawingSubstitutor,
                    false)
                != SUBSTITUTED_NONE;
      }
    }

    return substituted ? SUBSTITUTED_IN_PARAMETERS : SUBSTITUTED_NONE;
  }
  public static String[] getParameterString(ExtractInfoHelper helper, boolean useCanonicalText) {
    int i = 0;
    ParameterInfo[] infos = helper.getParameterInfos();
    int number = 0;
    for (ParameterInfo info : infos) {
      if (info.passAsParameter()) number++;
    }
    ArrayList<String> params = new ArrayList<String>();
    for (ParameterInfo info : infos) {
      if (info.passAsParameter()) {
        PsiType paramType = info.getType();
        final PsiPrimitiveType unboxed = PsiPrimitiveType.getUnboxedType(paramType);
        if (unboxed != null) paramType = unboxed;

        String paramTypeText;
        if (paramType == null
            || paramType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
            || paramType.equals(PsiType.NULL)) {
          paramTypeText = "";
        } else {
          paramTypeText =
              (useCanonicalText ? paramType.getCanonicalText() : paramType.getPresentableText())
                  + " ";
        }
        params.add(paramTypeText + info.getName() + (i < number - 1 ? ", " : ""));
        i++;
      }
    }
    return ArrayUtil.toStringArray(params);
  }
  private String[] suggestVariableNameByType(
      PsiType type, final VariableKind variableKind, boolean correctKeywords) {
    String longTypeName = getLongTypeName(type);
    CodeStyleSettings.TypeToNameMap map = getMapByVariableKind(variableKind);
    if (map != null && longTypeName != null) {
      if (type.equals(PsiType.NULL)) {
        longTypeName = CommonClassNames.JAVA_LANG_OBJECT;
      }
      String name = map.nameByType(longTypeName);
      if (name != null && isIdentifier(name)) {
        return new String[] {name};
      }
    }

    Collection<String> suggestions = new LinkedHashSet<String>();

    suggestNamesForCollectionInheritors(type, variableKind, suggestions, correctKeywords);
    suggestNamesFromGenericParameters(type, variableKind, suggestions, correctKeywords);

    String typeName = normalizeTypeName(getTypeName(type));
    if (typeName != null) {
      ContainerUtil.addAll(
          suggestions,
          getSuggestionsByName(
              typeName, variableKind, type instanceof PsiArrayType, correctKeywords));
    }

    return ArrayUtil.toStringArray(suggestions);
  }
  public static boolean areSignaturesEqualLightweight(
      @NotNull MethodSignature sig1, @NotNull MethodSignature sig2) {
    final boolean isConstructor1 = sig1.isConstructor();
    final boolean isConstructor2 = sig2.isConstructor();
    if (isConstructor1 != isConstructor2) return false;

    if (!isConstructor1
        || !(sig1 instanceof HierarchicalMethodSignature
            || sig2 instanceof HierarchicalMethodSignature)) {
      final String name1 = sig1.getName();
      final String name2 = sig2.getName();
      if (!name1.equals(name2)) return false;
    }

    final PsiType[] parameterTypes1 = sig1.getParameterTypes();
    final PsiType[] parameterTypes2 = sig2.getParameterTypes();
    if (parameterTypes1.length != parameterTypes2.length) return false;

    // optimization: check for really different types in method parameters
    for (int i = 0; i < parameterTypes1.length; i++) {
      final PsiType type1 = parameterTypes1[i];
      final PsiType type2 = parameterTypes2[i];
      if (type1 instanceof PsiPrimitiveType != type2 instanceof PsiPrimitiveType) return false;
      if (type1 instanceof PsiPrimitiveType && !type1.equals(type2)) return false;
    }

    return true;
  }
  private List<PsiType> matchingTypeParameters(
      PsiType[] paramVals, PsiTypeParameter[] params, ExpectedTypeInfo info) {
    PsiType type = info.getType();
    int kind = info.getKind();

    List<PsiType> result = new ArrayList<>();
    for (int i = 0; i < paramVals.length; i++) {
      PsiType val = paramVals[i];
      if (val != null) {
        switch (kind) {
          case ExpectedTypeInfo.TYPE_STRICTLY:
            if (val.equals(type)) result.add(myFactory.createType(params[i]));
            break;
          case ExpectedTypeInfo.TYPE_OR_SUBTYPE:
            if (type.isAssignableFrom(val)) result.add(myFactory.createType(params[i]));
            break;
          case ExpectedTypeInfo.TYPE_OR_SUPERTYPE:
            if (val.isAssignableFrom(type)) result.add(myFactory.createType(params[i]));
            break;
        }
      }
    }

    return result;
  }
  @Override
  protected void addCompletions(
      @NotNull final CompletionParameters parameters,
      final ProcessingContext processingContext,
      @NotNull final CompletionResultSet resultSet) {
    final PsiElement context = parameters.getPosition();

    final Pair<PsiClass, Integer> pair = getTypeParameterInfo(context);
    if (pair == null) return;

    PsiExpression expression = PsiTreeUtil.getContextOfType(context, PsiExpression.class, true);
    if (expression != null) {
      ExpectedTypeInfo[] types =
          ExpectedTypesProvider.getExpectedTypes(expression, true, false, false);
      if (types.length > 0) {
        for (ExpectedTypeInfo info : types) {
          PsiType type = info.getType();
          if (type instanceof PsiClassType && !type.equals(expression.getType())) {
            fillExpectedTypeArgs(
                resultSet,
                context,
                pair.first,
                pair.second,
                ((PsiClassType) type).resolveGenerics(),
                mySmart ? info.getTailType() : TailType.NONE);
          }
        }
        return;
      }
    }

    if (mySmart) {
      addInheritors(parameters, resultSet, pair.first, pair.second);
    }
  }
Esempio n. 8
0
  public static boolean canBeMigrated(final PsiElement e) {
    if (e == null) {
      return false;
    }

    final PsiElement element = normalizeElement(e);

    if (!element.getManager().isInProject(element)) {
      return false;
    }

    final PsiType type = TypeMigrationLabeler.getElementType(element);

    if (type != null) {
      final PsiType elemenType = type instanceof PsiArrayType ? type.getDeepComponentType() : type;

      if (elemenType instanceof PsiPrimitiveType) {
        return !elemenType.equals(PsiType.VOID);
      }

      final PsiClass aClass = ((PsiClassType) elemenType).resolve();

      return aClass != null /* && !aClass.hasTypeParameters()*/;
    }

    return false;
  }
 private static boolean isReturnTypeIsMoreSpecificThan(
     @NotNull HierarchicalMethodSignature thisSig, @NotNull HierarchicalMethodSignature thatSig) {
   PsiType thisRet = thisSig.getSubstitutor().substitute(thisSig.getMethod().getReturnType());
   PsiType thatRet = thatSig.getSubstitutor().substitute(thatSig.getMethod().getReturnType());
   return thatRet != null
       && thisRet != null
       && !thatRet.equals(thisRet)
       && TypeConversionUtil.isAssignable(thatRet, thisRet, false);
 }
 private static boolean typesAreEquivalent(@Nullable PsiType type1, @Nullable PsiType type2) {
   if (type1 == null) {
     return type2 == null;
   }
   if (type2 == null) {
     return false;
   }
   return type1.equals(type2);
 }
 private boolean typesAgree(@NotNull PsiType type1, @NotNull PsiType type2) {
   if (argumentsSupplied() && type1 instanceof PsiArrayType && !(type2 instanceof PsiArrayType)) {
     type1 = ((PsiArrayType) type1).getComponentType();
   }
   return argumentsSupplied()
       ? // resolve, otherwise same_name_variants
       TypesUtil.isAssignableWithoutConversions(type1, type2, myPlace)
       : type1.equals(type2);
 }
    @NotNull
    @Override
    public MyResult weigh(@NotNull LookupElement item) {
      final Object object = item.getObject();

      if (object instanceof PsiClass) {
        if (object instanceof PsiTypeParameter) return MyResult.typeParameter;

        if (myTypeParameter != null
            && object.equals(
                PsiUtil.resolveClassInType(
                    TypeConversionUtil.typeParameterErasure(myTypeParameter)))) {
          return MyResult.exactlyExpected;
        }
      }

      if (myExpectedTypes == null) return MyResult.normal;

      PsiType itemType = JavaCompletionUtil.getLookupElementType(item);
      if (itemType == null || !itemType.isValid()) return MyResult.normal;

      if (object instanceof PsiClass) {
        for (final ExpectedTypeInfo info : myExpectedTypes) {
          if (TypeConversionUtil.erasure(info.getType().getDeepComponentType())
              .equals(TypeConversionUtil.erasure(itemType))) {
            return AbstractExpectedTypeSkipper.skips(item, myLocation)
                ? MyResult.expectedNoSelect
                : MyResult.exactlyExpected;
          }
        }
      }

      for (final ExpectedTypeInfo expectedInfo : myExpectedTypes) {
        final PsiType defaultType = expectedInfo.getDefaultType();
        final PsiType expectedType = expectedInfo.getType();
        if (!expectedType.isValid()) {
          return MyResult.normal;
        }

        if (defaultType != expectedType) {
          if (defaultType.equals(itemType)) {
            return MyResult.exactlyDefault;
          }

          if (defaultType.isAssignableFrom(itemType)) {
            return MyResult.ofDefaultType;
          }
        }
        if (PsiType.VOID.equals(itemType) && PsiType.VOID.equals(expectedType)) {
          return MyResult.exactlyExpected;
        }
      }

      return MyResult.normal;
    }
Esempio n. 13
0
 @Nullable
 public static PsiMethod findPropertyGetterWithType(
     String propertyName, boolean isStatic, PsiType type, Iterator<PsiMethod> methods) {
   while (methods.hasNext()) {
     PsiMethod method = methods.next();
     if (method.hasModifierProperty(PsiModifier.STATIC) != isStatic) continue;
     if (isSimplePropertyGetter(method)) {
       if (getPropertyNameByGetter(method).equals(propertyName)) {
         if (type.equals(method.getReturnType())) return method;
       }
     }
   }
   return null;
 }
    @Override
    @Nullable
    public PsiType fun(final PsiMethodCallExpression call) {
      PsiReferenceExpression methodExpression = call.getMethodExpression();
      PsiType theOnly = null;
      final JavaResolveResult[] results = methodExpression.multiResolve(false);
      LanguageLevel languageLevel = PsiUtil.getLanguageLevel(call);

      final PsiElement callParent = PsiUtil.skipParenthesizedExprUp(call.getParent());
      final PsiExpressionList parentArgList;
      if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
        parentArgList =
            callParent instanceof PsiConditionalExpression
                    && !PsiPolyExpressionUtil.isPolyExpression((PsiExpression) callParent)
                ? null
                : PsiTreeUtil.getParentOfType(call, PsiExpressionList.class);
      } else {
        parentArgList = null;
      }
      final MethodCandidateInfo.CurrentCandidateProperties properties =
          MethodCandidateInfo.getCurrentMethod(parentArgList);
      final boolean genericMethodCall =
          properties != null && properties.getInfo().isToInferApplicability();

      for (int i = 0; i < results.length; i++) {
        final JavaResolveResult candidateInfo = results[i];

        if (genericMethodCall
            && PsiPolyExpressionUtil.isMethodCallPolyExpression(
                call, (PsiMethod) candidateInfo.getElement())) {
          if (callParent instanceof PsiAssignmentExpression) {
            return null;
          }
          LOG.error("poly expression evaluation during overload resolution");
        }

        final PsiType type = getResultType(call, methodExpression, candidateInfo, languageLevel);
        if (type == null) {
          return null;
        }

        if (i == 0) {
          theOnly = type;
        } else if (!theOnly.equals(type)) {
          return null;
        }
      }

      return PsiClassImplUtil.correctType(theOnly, call.getResolveScope());
    }
    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      PsiTypeItem that = (PsiTypeItem) o;

      if (myType == null) {
        if (that.myType != null) return false;
      } else {
        if (!myType.equals(that.myType)) return false;
      }

      return true;
    }
Esempio n. 16
0
 private void suggestNamesForCollectionInheritors(
     final PsiType type,
     final VariableKind variableKind,
     final Collection<String> suggestions,
     final boolean correctKeywords) {
   PsiType componentType = PsiUtil.extractIterableTypeParameter(type, false);
   if (componentType == null || componentType.equals(type)) {
     return;
   }
   String typeName = normalizeTypeName(getTypeName(componentType));
   if (typeName != null) {
     ContainerUtil.addAll(
         suggestions, getSuggestionsByName(typeName, variableKind, true, correctKeywords));
   }
 }
  private static AllowedValues getAllowedValuesFromMagic(
      @NotNull PsiModifierListOwner element, @NotNull PsiType type, PsiAnnotation magic) {
    if (magic == null) return null;
    PsiAnnotationMemberValue[] allowedValues;
    final boolean canBeOred;
    if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.LONG_RANK) {
      PsiAnnotationMemberValue intValues = magic.findAttributeValue("intValues");
      allowedValues =
          intValues instanceof PsiArrayInitializerMemberValue
              ? ((PsiArrayInitializerMemberValue) intValues).getInitializers()
              : PsiAnnotationMemberValue.EMPTY_ARRAY;
      if (allowedValues.length == 0) {
        PsiAnnotationMemberValue orValue = magic.findAttributeValue("flags");
        allowedValues =
            orValue instanceof PsiArrayInitializerMemberValue
                ? ((PsiArrayInitializerMemberValue) orValue).getInitializers()
                : PsiAnnotationMemberValue.EMPTY_ARRAY;
        canBeOred = true;
      } else {
        canBeOred = false;
      }
    } else if (type.equals(
        PsiType.getJavaLangString(
            element.getManager(), GlobalSearchScope.allScope(element.getProject())))) {
      PsiAnnotationMemberValue strValuesAttr = magic.findAttributeValue("stringValues");
      allowedValues =
          strValuesAttr instanceof PsiArrayInitializerMemberValue
              ? ((PsiArrayInitializerMemberValue) strValuesAttr).getInitializers()
              : PsiAnnotationMemberValue.EMPTY_ARRAY;
      canBeOred = false;
    } else {
      return null; // other types not supported
    }

    if (allowedValues.length != 0) {
      return new AllowedValues(allowedValues, canBeOred);
    }

    // last resort: try valuesFromClass
    PsiAnnotationMemberValue[] values = readFromClass("valuesFromClass", magic, type);
    boolean ored = false;
    if (values == null) {
      values = readFromClass("flagsFromClass", magic, type);
      ored = true;
    }
    if (values == null) return null;
    return new AllowedValues(values, ored);
  }
  @Nullable
  private static String doCheckRepeatableAnnotation(@NotNull PsiAnnotation annotation) {
    PsiAnnotationOwner owner = annotation.getOwner();
    if (!(owner instanceof PsiModifierList)) return null;
    PsiElement target = ((PsiModifierList) owner).getParent();
    if (!(target instanceof PsiClass) || !((PsiClass) target).isAnnotationType()) return null;
    PsiClass container = getRepeatableContainer(annotation);
    if (container == null) return null;

    PsiMethod[] methods = container.findMethodsByName("value", false);
    if (methods.length == 0) {
      return JavaErrorMessages.message(
          "annotation.container.no.value", container.getQualifiedName());
    }

    if (methods.length == 1) {
      PsiType expected =
          new PsiImmediateClassType((PsiClass) target, PsiSubstitutor.EMPTY).createArrayType();
      if (!expected.equals(methods[0].getReturnType())) {
        return JavaErrorMessages.message(
            "annotation.container.bad.type",
            container.getQualifiedName(),
            JavaHighlightUtil.formatType(expected));
      }
    }

    RetentionPolicy targetPolicy = getRetentionPolicy((PsiClass) target);
    if (targetPolicy != null) {
      RetentionPolicy containerPolicy = getRetentionPolicy(container);
      if (containerPolicy != null && targetPolicy.compareTo(containerPolicy) > 0) {
        return JavaErrorMessages.message(
            "annotation.container.low.retention", container.getQualifiedName(), containerPolicy);
      }
    }

    Set<PsiAnnotation.TargetType> repeatableTargets =
        PsiImplUtil.getAnnotationTargets((PsiClass) target);
    if (repeatableTargets != null) {
      Set<PsiAnnotation.TargetType> containerTargets = PsiImplUtil.getAnnotationTargets(container);
      if (containerTargets != null && !repeatableTargets.containsAll(containerTargets)) {
        return JavaErrorMessages.message(
            "annotation.container.wide.target", container.getQualifiedName());
      }
    }

    return null;
  }
Esempio n. 19
0
  @Nullable
  public static PsiField findPropertyFieldWithType(
      Project project,
      String propertyName,
      boolean isStatic,
      PsiType type,
      Iterator<PsiField> fields) {
    while (fields.hasNext()) {
      PsiField field = fields.next();
      if (field.hasModifierProperty(PsiModifier.STATIC) != isStatic) continue;
      if (propertyName.equals(suggestPropertyName(project, field))) {
        if (type.equals(field.getType())) return field;
      }
    }

    return null;
  }
Esempio n. 20
0
  @Nullable
  private PsiMethod[] getChangeRoots(final PsiMethod method, @NotNull PsiType returnType) {
    if (!myFixWholeHierarchy) return new PsiMethod[] {method};

    final PsiMethod[] methods = method.findDeepestSuperMethods();

    if (methods.length > 0) {
      for (PsiMethod psiMethod : methods) {
        if (returnType.equals(psiMethod.getReturnType())) {
          return new PsiMethod[] {method};
        }
      }
      return methods;
    }
    // no - only base
    return new PsiMethod[] {method};
  }
 public boolean satisfiedBy(PsiElement element) {
   if (!(element instanceof PsiSwitchStatement)) {
     return false;
   }
   final PsiSwitchStatement switchStatement = (PsiSwitchStatement) element;
   final PsiCodeBlock body = switchStatement.getBody();
   if (body == null) {
     return false;
   }
   final PsiExpression expression = switchStatement.getExpression();
   if (expression == null) {
     return false;
   }
   final PsiType type = expression.getType();
   if (!(type instanceof PsiClassType)) {
     return false;
   }
   final PsiClass enumClass = ((PsiClassType) type).resolve();
   if (enumClass == null || !enumClass.isEnum()) {
     return false;
   }
   final PsiField[] fields = enumClass.getFields();
   final Set<String> enumElements = new HashSet<String>(fields.length);
   for (final PsiField field : fields) {
     final PsiType fieldType = field.getType();
     if (fieldType.equals(type)) {
       final String fieldName = field.getName();
       enumElements.add(fieldName);
     }
   }
   final PsiStatement[] statements = body.getStatements();
   for (PsiStatement statement : statements) {
     if (statement instanceof PsiSwitchLabelStatement) {
       final PsiSwitchLabelStatement labelStatement = (PsiSwitchLabelStatement) statement;
       final PsiExpression value = labelStatement.getCaseValue();
       if (value != null) {
         final String valueText = value.getText();
         enumElements.remove(valueText);
       }
     }
   }
   if (enumElements.isEmpty()) {
     return false;
   }
   return !ErrorUtil.containsError(element);
 }
  private void updateRefMethod(
      PsiElement psiResolved,
      RefElement refResolved,
      PsiElement refExpression,
      final PsiElement psiFrom,
      final RefElement refFrom) {
    PsiMethod psiMethod = (PsiMethod) psiResolved;
    RefMethodImpl refMethod = (RefMethodImpl) refResolved;

    PsiMethodCallExpression call =
        PsiTreeUtil.getParentOfType(refExpression, PsiMethodCallExpression.class);
    if (call != null) {
      PsiType returnType = psiMethod.getReturnType();
      if (!psiMethod.isConstructor() && returnType != PsiType.VOID) {
        if (!(call.getParent() instanceof PsiExpressionStatement)) {
          refMethod.setReturnValueUsed(true);
        }

        addTypeReference(psiFrom, returnType, refFrom.getRefManager());
      }

      PsiExpressionList argumentList = call.getArgumentList();
      if (argumentList.getExpressions().length > 0) {
        refMethod.updateParameterValues(argumentList.getExpressions());
      }

      final PsiExpression psiExpression = call.getMethodExpression().getQualifierExpression();
      if (psiExpression != null) {
        final PsiType usedType = psiExpression.getType();
        if (usedType != null) {
          final String fqName = psiMethod.getContainingClass().getQualifiedName();
          if (fqName != null) {
            final PsiClassType methodOwnerType =
                JavaPsiFacade.getInstance(call.getProject())
                    .getElementFactory()
                    .createTypeByFQClassName(
                        fqName, GlobalSearchScope.allScope(psiMethod.getProject()));
            if (!usedType.equals(methodOwnerType)) {
              refMethod.setCalledOnSubClass(true);
            }
          }
        }
      }
    }
  }
 private boolean isIteratorNext(
   PsiElement element, String iteratorName, PsiType contentType) {
   if (element == null) {
     return false;
   }
   if (element instanceof PsiTypeCastExpression) {
     final PsiTypeCastExpression castExpression =
       (PsiTypeCastExpression)element;
     final PsiType type = castExpression.getType();
     if (type == null) {
       return false;
     }
     if (!type.equals(contentType)) {
       return false;
     }
     final PsiExpression operand =
       castExpression.getOperand();
     return isIteratorNext(operand, iteratorName, contentType);
   }
   if (!(element instanceof PsiMethodCallExpression)) {
     return false;
   }
   final PsiMethodCallExpression callExpression =
     (PsiMethodCallExpression)element;
   final PsiExpressionList argumentList =
     callExpression.getArgumentList();
   final PsiExpression[] args = argumentList.getExpressions();
   if (args.length != 0) {
     return false;
   }
   final PsiReferenceExpression reference =
     callExpression.getMethodExpression();
   final PsiExpression qualifier = reference.getQualifierExpression();
   if (qualifier == null) {
     return false;
   }
   if (!iteratorName.equals(qualifier.getText())) {
     return false;
   }
   final String referenceName = reference.getReferenceName();
   return HardcodedMethodConstants.NEXT.equals(referenceName);
 }
 private void checkExpression(@NotNull PsiExpression expression) {
   if (expression.getParent() instanceof PsiParenthesizedExpression) {
     return;
   }
   final PsiType expressionType = expression.getType();
   if (expressionType == null
       || expressionType.equals(PsiType.VOID)
       || !TypeConversionUtil.isPrimitiveAndNotNull(expressionType)) {
     return;
   }
   final PsiPrimitiveType primitiveType = (PsiPrimitiveType) expressionType;
   final PsiClassType boxedType = primitiveType.getBoxedType(expression);
   if (boxedType == null) {
     return;
   }
   final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false);
   if (expectedType == null || ClassUtils.isPrimitive(expectedType)) {
     return;
   }
   if (!expectedType.isAssignableFrom(boxedType)) {
     // JLS 5.2 Assignment Conversion
     // check if a narrowing primitive conversion is applicable
     if (!(expectedType instanceof PsiClassType) || !PsiUtil.isConstantExpression(expression)) {
       return;
     }
     final PsiClassType classType = (PsiClassType) expectedType;
     final String className = classType.getCanonicalText();
     if (!convertableBoxedClassNames.contains(className)) {
       return;
     }
     if (!PsiType.BYTE.equals(expressionType)
         && !PsiType.CHAR.equals(expressionType)
         && !PsiType.SHORT.equals(expressionType)
         && !PsiType.INT.equals(expressionType)) {
       return;
     }
   }
   if (ignoreAddedToCollection && isAddedToCollection(expression)) {
     return;
   }
   registerError(expression);
 }
 private boolean isListElementDeclaration(
     PsiStatement statement, PsiVariable listVariable, String indexName, PsiType type) {
   if (!(statement instanceof PsiDeclarationStatement)) {
     return false;
   }
   final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement) statement;
   final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
   if (declaredElements.length != 1) {
     return false;
   }
   final PsiElement declaredElement = declaredElements[0];
   if (!(declaredElement instanceof PsiVariable)) {
     return false;
   }
   final PsiVariable variable = (PsiVariable) declaredElement;
   final PsiExpression initializer = variable.getInitializer();
   if (!isListGetLookup(initializer, indexName, listVariable)) {
     return false;
   }
   return type != null && type.equals(variable.getType());
 }
 private static boolean forEachStatementsAreEquivalent(
     @NotNull PsiForeachStatement statement1, @NotNull PsiForeachStatement statement2) {
   final PsiExpression value1 = statement1.getIteratedValue();
   final PsiExpression value2 = statement2.getIteratedValue();
   if (!expressionsAreEquivalent(value1, value2)) {
     return false;
   }
   final PsiParameter parameter1 = statement1.getIterationParameter();
   final PsiParameter parameter2 = statement1.getIterationParameter();
   final String name1 = parameter1.getName();
   final String name2 = parameter2.getName();
   if (!name1.equals(name2)) {
     return false;
   }
   final PsiType type1 = parameter1.getType();
   if (!type1.equals(parameter2.getType())) {
     return false;
   }
   final PsiStatement body1 = statement1.getBody();
   final PsiStatement body2 = statement2.getBody();
   return statementsAreEquivalent(body1, body2);
 }
  private static boolean compareParamTypes(
      @NotNull PsiManager manager, @NotNull PsiType type1, @NotNull PsiType type2) {
    if (type1 instanceof PsiArrayType) {
      return type2 instanceof PsiArrayType
          && compareParamTypes(
              manager,
              ((PsiArrayType) type1).getComponentType(),
              ((PsiArrayType) type2).getComponentType());
    }

    if (!(type1 instanceof PsiClassType) || !(type2 instanceof PsiClassType)) {
      return type1.equals(type2);
    }

    PsiClass class1 = ((PsiClassType) type1).resolve();
    PsiClass class2 = ((PsiClassType) type2).resolve();

    if (class1 instanceof PsiTypeParameter && class2 instanceof PsiTypeParameter) {
      return Comparing.equal(class1.getName(), class2.getName())
          && ((PsiTypeParameter) class1).getIndex() == ((PsiTypeParameter) class2).getIndex();
    }

    return manager.areElementsEquivalent(class1, class2);
  }
Esempio n. 28
0
  private String[] suggestVariableNameByType(
      final PsiType type,
      final VariableKind variableKind,
      final boolean correctKeywords,
      boolean skipIndices) {
    String longTypeName = skipIndices ? type.getCanonicalText() : getLongTypeName(type);
    CodeStyleSettings.TypeToNameMap map = getMapByVariableKind(variableKind);
    if (map != null && longTypeName != null) {
      if (type.equals(PsiType.NULL)) {
        longTypeName = CommonClassNames.JAVA_LANG_OBJECT;
      }
      String name = map.nameByType(longTypeName);
      if (name != null && isIdentifier(name)) {
        return new String[] {name};
      }
    }

    final Collection<String> suggestions = new LinkedHashSet<String>();

    final PsiClass psiClass =
        !skipIndices && type instanceof PsiClassType ? ((PsiClassType) type).resolve() : null;

    if (!skipIndices) {
      suggestNamesForCollectionInheritors(type, variableKind, suggestions, correctKeywords);

      if (psiClass != null
          && CommonClassNames.JAVA_UTIL_OPTIONAL.equals(psiClass.getQualifiedName())
          && ((PsiClassType) type).getParameterCount() == 1) {
        PsiType optionalContent = ((PsiClassType) type).getParameters()[0];
        Collections.addAll(
            suggestions,
            suggestVariableNameByType(optionalContent, variableKind, correctKeywords, false));
      }

      suggestNamesFromGenericParameters(type, variableKind, suggestions, correctKeywords);
    }

    String typeName = getTypeName(type, !skipIndices);

    if (typeName != null) {
      typeName = normalizeTypeName(typeName);
      ContainerUtil.addAll(
          suggestions,
          getSuggestionsByName(
              typeName, variableKind, type instanceof PsiArrayType, correctKeywords));
    }

    if (psiClass != null && psiClass.getContainingClass() != null) {
      InheritanceUtil.processSupers(
          psiClass,
          false,
          new Processor<PsiClass>() {
            @Override
            public boolean process(PsiClass superClass) {
              if (PsiTreeUtil.isAncestor(superClass, psiClass, true)) {
                ContainerUtil.addAll(
                    suggestions,
                    getSuggestionsByName(
                        superClass.getName(), variableKind, false, correctKeywords));
              }
              return false;
            }
          });
    }

    return ArrayUtil.toStringArray(suggestions);
  }
 @Nullable
 private String createCollectionIterationText(@NotNull PsiForStatement forStatement)
     throws IncorrectOperationException {
   final PsiStatement body = forStatement.getBody();
   final PsiStatement firstStatement = getFirstStatement(body);
   final PsiStatement initialization = forStatement.getInitialization();
   if (!(initialization instanceof PsiDeclarationStatement)) {
     return null;
   }
   final PsiDeclarationStatement declaration = (PsiDeclarationStatement) initialization;
   final PsiElement declaredIterator = declaration.getDeclaredElements()[0];
   if (!(declaredIterator instanceof PsiVariable)) {
     return null;
   }
   final PsiVariable iteratorVariable = (PsiVariable) declaredIterator;
   final PsiMethodCallExpression initializer =
       (PsiMethodCallExpression) iteratorVariable.getInitializer();
   if (initializer == null) {
     return null;
   }
   final PsiType iteratorType = initializer.getType();
   if (iteratorType == null) {
     return null;
   }
   final PsiType iteratorContentType = extractContentTypeFromType(iteratorType);
   final PsiType iteratorVariableType = iteratorVariable.getType();
   final PsiType contentType;
   final PsiClassType javaLangObject = TypeUtils.getObjectType(forStatement);
   if (iteratorContentType == null) {
     final PsiType iteratorVariableContentType =
         extractContentTypeFromType(iteratorVariableType);
     if (iteratorVariableContentType == null) {
       contentType = javaLangObject;
     } else {
       contentType = iteratorVariableContentType;
     }
   } else {
     contentType = iteratorContentType;
   }
   final PsiReferenceExpression methodExpression = initializer.getMethodExpression();
   final PsiExpression collection = methodExpression.getQualifierExpression();
   final String iteratorName = iteratorVariable.getName();
   final boolean isDeclaration =
       isIteratorNextDeclaration(firstStatement, iteratorName, contentType);
   final PsiStatement statementToSkip;
   @NonNls final String finalString;
   final String contentVariableName;
   if (isDeclaration) {
     final PsiDeclarationStatement declarationStatement =
         (PsiDeclarationStatement) firstStatement;
     assert declarationStatement != null;
     final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
     final PsiElement declaredElement = declaredElements[0];
     if (!(declaredElement instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable) declaredElement;
     contentVariableName = variable.getName();
     statementToSkip = declarationStatement;
     if (variable.hasModifierProperty(PsiModifier.FINAL)) {
       finalString = "final ";
     } else {
       finalString = "";
     }
   } else {
     if (collection instanceof PsiReferenceExpression) {
       final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) collection;
       final String collectionName = referenceExpression.getReferenceName();
       contentVariableName = createNewVariableName(forStatement, contentType, collectionName);
     } else {
       contentVariableName = createNewVariableName(forStatement, contentType, null);
     }
     final Project project = forStatement.getProject();
     final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
     if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
       finalString = "final ";
     } else {
       finalString = "";
     }
     statementToSkip = null;
   }
   final String contentTypeString = contentType.getCanonicalText();
   @NonNls final StringBuilder out = new StringBuilder();
   out.append("for(");
   out.append(finalString);
   out.append(contentTypeString);
   out.append(' ');
   out.append(contentVariableName);
   out.append(": ");
   if (!contentType.equals(javaLangObject)) {
     @NonNls final String iterableTypeString = "java.lang.Iterable<" + contentTypeString + '>';
     if (iteratorContentType == null) {
       out.append('(');
       out.append(iterableTypeString);
       out.append(')');
     }
   }
   if (collection == null) {
     out.append("this");
   } else {
     out.append(collection.getText());
   }
   out.append(')');
   replaceIteratorNext(
       body, contentVariableName, iteratorName, statementToSkip, out, contentType);
   return out.toString();
 }
 @Override
 public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) {
   super.visitTypeCastExpression(expression);
   final PsiExpression operand = expression.getOperand();
   if (operand == null) {
     return;
   }
   final PsiType operandType = operand.getType();
   if (operandType == null) {
     return;
   }
   final PsiType type = expression.getType();
   if (type == null) {
     return;
   }
   final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, true);
   if (expectedType == null) {
     return;
   }
   if (expectedType.equals(type)) {
     return;
   }
   final PsiClass resolved = PsiUtil.resolveClassInType(expectedType);
   if (resolved != null && !resolved.isPhysical()) {
     return;
   }
   if (expectedType.isAssignableFrom(operandType)) {
     // then it's redundant, and caught by the built-in exception
     return;
   }
   if (isTypeParameter(expectedType)) {
     return;
   }
   if (expectedType instanceof PsiArrayType) {
     final PsiArrayType arrayType = (PsiArrayType) expectedType;
     final PsiType componentType = arrayType.getDeepComponentType();
     if (isTypeParameter(componentType)) {
       return;
     }
   }
   if (type instanceof PsiPrimitiveType || expectedType instanceof PsiPrimitiveType) {
     return;
   }
   if (PsiPrimitiveType.getUnboxedType(type) != null
       || PsiPrimitiveType.getUnboxedType(expectedType) != null) {
     return;
   }
   if (expectedType instanceof PsiClassType) {
     final PsiClassType expectedClassType = (PsiClassType) expectedType;
     final PsiClassType expectedRawType = expectedClassType.rawType();
     if (type.equals(expectedRawType)) {
       return;
     }
     if (type instanceof PsiClassType) {
       final PsiClassType classType = (PsiClassType) type;
       final PsiClassType rawType = classType.rawType();
       if (rawType.equals(expectedRawType)) {
         return;
       }
     }
     if (type instanceof PsiArrayType) {
       return;
     }
   }
   if (ignoreInMatchingInstanceof && InstanceOfUtils.hasAgreeingInstanceof(expression)) {
     return;
   }
   final PsiTypeElement castTypeElement = expression.getCastType();
   if (castTypeElement == null) {
     return;
   }
   registerError(castTypeElement, expectedType);
 }