private static PsiType doGetType(PsiBinaryExpressionImpl param) {
    PsiExpression lOperand = param.getLOperand();
    PsiExpression rOperand = param.getROperand();
    if (rOperand == null) return null;
    PsiType rType = rOperand.getType();
    IElementType sign = param.getOperationTokenType();
    // optimization: if we can calculate type based on right type only
    PsiType type = TypeConversionUtil.calcTypeForBinaryExpression(null, rType, sign, false);
    if (type != TypeConversionUtil.NULL_TYPE) return type;

    if (lOperand instanceof PsiBinaryExpressionImpl
        && !JavaResolveCache.getInstance(param.getProject()).isTypeCached(lOperand)) {
      // cache all intermediate expression types from bottom up
      PsiBinaryExpressionImpl topLevel = param;
      PsiElement element = param;
      while (element instanceof PsiBinaryExpressionImpl) {
        topLevel = (PsiBinaryExpressionImpl) element;
        element = element.getParent();
      }
      topLevel.accept(
          new JavaRecursiveElementWalkingVisitor() {
            @Override
            protected void elementFinished(PsiElement element) {
              if (element instanceof PsiExpression) {
                ProgressIndicatorProvider.checkCanceled();
                ((PsiExpression) element).getType();
              }
            }
          });
    }
    PsiType lType = lOperand.getType();
    return TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, sign, true);
  }
 @Nullable
 private static PsiType getInferredTypes(
     GrReferenceExpressionImpl refExpr, @Nullable PsiElement resolved) {
   final GrExpression qualifier = refExpr.getQualifier();
   if (qualifier == null && !(resolved instanceof PsiClass)) {
     return TypeInferenceHelper.getCurrentContext().getVariableType(refExpr);
   } else if (qualifier != null) {
     // map access
     PsiType qType = qualifier.getType();
     if (qType instanceof PsiClassType && !(qType instanceof GrMapType)) {
       PsiClassType.ClassResolveResult qResult = ((PsiClassType) qType).resolveGenerics();
       PsiClass clazz = qResult.getElement();
       if (clazz != null) {
         PsiClass mapClass =
             JavaPsiFacade.getInstance(refExpr.getProject())
                 .findClass(CommonClassNames.JAVA_UTIL_MAP, refExpr.getResolveScope());
         if (mapClass != null && mapClass.getTypeParameters().length == 2) {
           PsiSubstitutor substitutor =
               TypeConversionUtil.getClassSubstitutor(mapClass, clazz, qResult.getSubstitutor());
           if (substitutor != null) {
             return TypeConversionUtil.erasure(
                 substitutor.substitute(mapClass.getTypeParameters()[1]));
           }
         }
       }
     }
   }
   return null;
 }
 private static boolean acceptExtendsBound(PsiClassType extendsBound, int depth) {
   PsiType[] parameters = extendsBound.getParameters();
   if (parameters.length == 1) {
     PsiType argType = parameters[0];
     if (argType instanceof PsiCapturedWildcardType && depth == 0) {
       argType = ((PsiCapturedWildcardType) argType).getWildcard();
     }
     if (argType instanceof PsiWildcardType) {
       if (!((PsiWildcardType) argType).isBounded()) return true;
       final PsiType bound = ((PsiWildcardType) argType).getExtendsBound();
       if (bound instanceof PsiClassType
           && TypeConversionUtil.erasure(bound).equals(TypeConversionUtil.erasure(extendsBound))) {
         return acceptExtendsBound((PsiClassType) bound, depth + 1);
       }
       if (bound instanceof PsiIntersectionType) {
         for (PsiType extendsType : ((PsiIntersectionType) bound).getConjuncts()) {
           if (acceptExtendsBound(extendsBound, extendsType)) {
             return true;
           }
         }
       }
     }
   }
   return false;
 }
 private void checkExpression(PsiExpression expression) {
   if (expression.getParent() instanceof PsiParenthesizedExpression) {
     return;
   }
   final PsiType expressionType = expression.getType();
   if (expressionType == null) {
     return;
   }
   if (expressionType.getArrayDimensions() > 0) {
     // a horrible hack to get around what happens when you pass
     // an array to a vararg expression
     return;
   }
   if (TypeConversionUtil.isPrimitiveAndNotNull(expressionType)) {
     return;
   }
   final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(expressionType);
   if (unboxedType == null) {
     return;
   }
   final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false);
   if (expectedType == null) {
     return;
   }
   if (!TypeConversionUtil.isPrimitiveAndNotNull(expectedType)) {
     return;
   }
   if (!expectedType.isAssignableFrom(unboxedType)) {
     return;
   }
   registerError(expression, expression);
 }
 @Nullable
 private static PsiType getTypeFromMapAccess(@NotNull GrReferenceExpressionImpl ref) {
   // map access
   GrExpression qualifier = ref.getQualifierExpression();
   if (qualifier != null) {
     PsiType qType = qualifier.getNominalType();
     if (qType instanceof PsiClassType) {
       PsiClassType.ClassResolveResult qResult = ((PsiClassType) qType).resolveGenerics();
       PsiClass clazz = qResult.getElement();
       if (clazz != null) {
         PsiClass mapClass =
             JavaPsiFacade.getInstance(ref.getProject())
                 .findClass(CommonClassNames.JAVA_UTIL_MAP, ref.getResolveScope());
         if (mapClass != null && mapClass.getTypeParameters().length == 2) {
           PsiSubstitutor substitutor =
               TypeConversionUtil.getClassSubstitutor(mapClass, clazz, qResult.getSubstitutor());
           if (substitutor != null) {
             return TypeConversionUtil.erasure(
                 substitutor.substitute(mapClass.getTypeParameters()[1]));
           }
         }
       }
     }
   }
   return null;
 }
 @Nullable
 public static PsiType getLeastUpperBound(PsiType type1, PsiType type2, PsiManager manager) {
   if (TypeConversionUtil.isPrimitiveAndNotNull(type1)
       || TypeConversionUtil.isPrimitiveAndNotNull(type2)) return null;
   if (TypeConversionUtil.isNullType(type1)) return type2;
   if (TypeConversionUtil.isNullType(type2)) return type1;
   if (Comparing.equal(type1, type2)) return type1;
   return getLeastUpperBound(type1, type2, new LinkedHashSet<Pair<PsiType, PsiType>>(), manager);
 }
Example #7
0
  private static boolean changeClassTypeArgument(
      PsiMethod myMethod,
      Project project,
      PsiType superReturnType,
      PsiClass superClass,
      Editor editor,
      PsiType returnType) {
    if (superClass == null || !superClass.hasTypeParameters()) return true;
    final PsiClass superReturnTypeClass = PsiUtil.resolveClassInType(superReturnType);
    if (superReturnTypeClass == null
        || !(superReturnTypeClass instanceof PsiTypeParameter
            || superReturnTypeClass.hasTypeParameters())) return true;

    final PsiClass derivedClass = myMethod.getContainingClass();
    if (derivedClass == null) return true;

    final PsiReferenceParameterList referenceParameterList =
        findTypeArgumentsList(superClass, derivedClass);
    if (referenceParameterList == null) return true;

    final PsiElement resolve =
        ((PsiJavaCodeReferenceElement) referenceParameterList.getParent()).resolve();
    if (!(resolve instanceof PsiClass)) return true;
    final PsiClass baseClass = (PsiClass) resolve;

    if (returnType instanceof PsiPrimitiveType) {
      returnType = ((PsiPrimitiveType) returnType).getBoxedType(derivedClass);
    }

    final PsiSubstitutor superClassSubstitutor =
        TypeConversionUtil.getSuperClassSubstitutor(superClass, baseClass, PsiSubstitutor.EMPTY);
    final PsiType superReturnTypeInBaseClassType =
        superClassSubstitutor.substitute(superReturnType);
    final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(project).getResolveHelper();
    final PsiSubstitutor psiSubstitutor =
        resolveHelper.inferTypeArguments(
            PsiTypesUtil.filterUnusedTypeParameters(
                superReturnTypeInBaseClassType, baseClass.getTypeParameters()),
            new PsiType[] {superReturnTypeInBaseClassType},
            new PsiType[] {returnType},
            PsiUtil.getLanguageLevel(superClass));

    final TypeMigrationRules rules = new TypeMigrationRules();
    final PsiSubstitutor compoundSubstitutor =
        TypeConversionUtil.getSuperClassSubstitutor(superClass, derivedClass, PsiSubstitutor.EMPTY)
            .putAll(psiSubstitutor);
    rules.setBoundScope(new LocalSearchScope(derivedClass));
    TypeMigrationProcessor.runHighlightingTypeMigration(
        project,
        editor,
        rules,
        referenceParameterList,
        JavaPsiFacade.getElementFactory(project).createType(baseClass, compoundSubstitutor));

    return false;
  }
    private static PsiType doFun(GrReferenceExpression refExpr) {
      if (ResolveUtil.isClassReference(refExpr)) {
        GrExpression qualifier = refExpr.getQualifier();
        LOG.assertTrue(qualifier != null);
        return TypesUtil.createJavaLangClassType(
            qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope());
      }

      if (PsiUtil.isCompileStatic(refExpr)) {
        final GroovyResolveResult resolveResult = refExpr.advancedResolve();
        final PsiElement resolvedF = resolveResult.getElement();
        final PsiType type;
        if (resolvedF instanceof GrField) {
          type = ((GrField) resolvedF).getType();
        } else if (resolvedF instanceof GrAccessorMethod) {
          type = ((GrAccessorMethod) resolvedF).getProperty().getType();
        } else {
          type = null;
        }
        if (type != null) {
          return resolveResult.getSubstitutor().substitute(type);
        }
      }

      final PsiElement resolved = refExpr.resolve();
      final PsiType nominal = refExpr.getNominalType();

      Boolean reassigned = GrReassignedLocalVarsChecker.isReassignedVar(refExpr);
      if (reassigned != null && reassigned.booleanValue()) {
        return GrReassignedLocalVarsChecker.getReassignedVarType(refExpr, true);
      }

      final PsiType inferred = getInferredTypes(refExpr, resolved);
      if (inferred == null) {
        if (nominal == null) {
          // inside nested closure we could still try to infer from variable initializer. Not sound,
          // but makes sense
          if (resolved instanceof GrVariable) {
            LOG.assertTrue(resolved.isValid());
            return ((GrVariable) resolved).getTypeGroovy();
          }
        }

        return nominal;
      }

      if (nominal == null) return inferred;
      if (!TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(nominal), inferred, false)) {
        if (resolved instanceof GrVariable
            && ((GrVariable) resolved).getTypeElementGroovy() != null) {
          return nominal;
        }
      }
      return inferred;
    }
    @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;
    }
Example #10
0
    private boolean isOverridden(
        PsiClass inheritor, PsiMethod method, PsiMethod superMethod, PsiClass superInterface) {
      // calculate substitutor of containingClass --> inheritor
      PsiSubstitutor substitutor =
          TypeConversionUtil.getSuperClassSubstitutor(
              myContainingClass, inheritor, PsiSubstitutor.EMPTY);
      // calculate substitutor of inheritor --> superInterface
      substitutor =
          TypeConversionUtil.getSuperClassSubstitutor(superInterface, inheritor, substitutor);

      return MethodSignatureUtil.isSubsignature(
          superMethod.getSignature(substitutor), method.getSignature(PsiSubstitutor.EMPTY));
    }
  public static PsiType captureReturnType(
      PsiMethodCallExpression call,
      PsiMethod method,
      PsiType ret,
      JavaResolveResult result,
      LanguageLevel languageLevel) {
    PsiSubstitutor substitutor = result.getSubstitutor();
    PsiType substitutedReturnType = substitutor.substitute(ret);
    if (substitutedReturnType == null) {
      return TypeConversionUtil.erasure(ret);
    }

    if (InferenceSession.wasUncheckedConversionPerformed(call)) {
      // 18.5.2
      // if unchecked conversion was necessary, then this substitution provides the parameter types
      // of the invocation type,
      // while the return type and thrown types are given by the erasure of m's type (without
      // applying θ').
      // due to https://bugs.openjdk.java.net/browse/JDK-8135087 erasure is called on
      // substitutedReturnType and not on ret type itself as by spec
      return TypeConversionUtil.erasure(substitutedReturnType);
    }

    // 15.12.2.6. Method Invocation Type
    // If unchecked conversion was necessary for the method to be applicable,
    // the parameter types of the invocation type are the parameter types of the method's type,
    // and the return type and thrown types are given by the erasures of the return type and thrown
    // types of the method's type.
    if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)
        && (method.hasTypeParameters()
            || JavaVersionService.getInstance().isAtLeast(call, JavaSdkVersion.JDK_1_8))
        && result instanceof MethodCandidateInfo
        && ((MethodCandidateInfo) result).isApplicable()) {
      final PsiType[] args = call.getArgumentList().getExpressionTypes();
      final boolean allowUncheckedConversion = false;
      final int applicabilityLevel =
          PsiUtil.getApplicabilityLevel(
              method, substitutor, args, languageLevel, allowUncheckedConversion, true);
      if (applicabilityLevel == MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE) {
        return TypeConversionUtil.erasure(substitutedReturnType);
      }
    }

    if (PsiUtil.isRawSubstitutor(method, substitutor)) {
      final PsiType returnTypeErasure = TypeConversionUtil.erasure(ret);
      if (Comparing.equal(TypeConversionUtil.erasure(substitutedReturnType), returnTypeErasure)) {
        return returnTypeErasure;
      }
    }
    return PsiUtil.captureToplevelWildcards(substitutedReturnType, call);
  }
 private boolean hardEquals(
     PsiModifierListOwner psiVar, PsiType varType, boolean negated, DfaVariableValue qualifier) {
   return psiVar == myVariable
       && Comparing.equal(
           TypeConversionUtil.erasure(varType), TypeConversionUtil.erasure(myVarType))
       && negated == myIsNegated
       && (myQualifier == null
           ? qualifier == null
           : myQualifier.hardEquals(
               qualifier.getPsiVariable(),
               qualifier.getVariableType(),
               qualifier.isNegated(),
               qualifier.getQualifier()));
 }
 public static boolean acceptExtendsBound(PsiType extendsType, PsiType extendsBound) {
   if (Comparing.equal(
       TypeConversionUtil.erasure(extendsType), TypeConversionUtil.erasure(extendsBound))) {
     if (extendsBound instanceof PsiClassType) {
       if (acceptExtendsBound((PsiClassType) extendsBound, 0)) return true;
     } else if (extendsBound instanceof PsiIntersectionType) {
       for (PsiType psiType : ((PsiIntersectionType) extendsBound).getConjuncts()) {
         if (psiType instanceof PsiClassType) {
           if (acceptExtendsBound((PsiClassType) psiType, 0)) return true;
         }
       }
     }
   }
   return false;
 }
  public static PsiType eliminateWildcards(PsiType type, final boolean eliminateInTypeArguments) {
    if (eliminateInTypeArguments && type instanceof PsiClassType) {
      PsiClassType classType = (PsiClassType) type;
      JavaResolveResult resolveResult = classType.resolveGenerics();
      PsiClass aClass = (PsiClass) resolveResult.getElement();
      if (aClass != null) {
        PsiManager manager = aClass.getManager();
        PsiTypeParameter[] typeParams = aClass.getTypeParameters();
        Map<PsiTypeParameter, PsiType> map = new HashMap<PsiTypeParameter, PsiType>();
        for (PsiTypeParameter typeParam : typeParams) {
          PsiType substituted = resolveResult.getSubstitutor().substitute(typeParam);
          if (substituted instanceof PsiWildcardType) {
            substituted = ((PsiWildcardType) substituted).getBound();
            if (substituted == null)
              substituted = TypeConversionUtil.typeParameterErasure(typeParam);
          }
          map.put(typeParam, substituted);
        }

        PsiElementFactory factory =
            JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
        PsiSubstitutor substitutor = factory.createSubstitutor(map);
        type = factory.createType(aClass, substitutor);
      }
    } else if (type instanceof PsiArrayType) {
      return eliminateWildcards(((PsiArrayType) type).getComponentType(), false).createArrayType();
    } else if (type instanceof PsiWildcardType) {
      final PsiType bound = ((PsiWildcardType) type).getBound();
      return bound != null ? bound : ((PsiWildcardType) type).getExtendsBound(); // object
    } else if (type instanceof PsiCapturedWildcardType && !eliminateInTypeArguments) {
      return eliminateWildcards(
          ((PsiCapturedWildcardType) type).getWildcard(), eliminateInTypeArguments);
    }
    return type;
  }
 private static void addDefaultConstructor(
     JavaChangeInfo changeInfo, PsiClass aClass, final UsageInfo[] usages)
     throws IncorrectOperationException {
   if (!(aClass instanceof PsiAnonymousClass)) {
     PsiElementFactory factory = JavaPsiFacade.getElementFactory(aClass.getProject());
     PsiMethod defaultConstructor =
         factory.createMethodFromText(aClass.getName() + "(){}", aClass);
     defaultConstructor =
         (PsiMethod)
             CodeStyleManager.getInstance(aClass.getProject()).reformat(defaultConstructor);
     defaultConstructor = (PsiMethod) aClass.add(defaultConstructor);
     PsiUtil.setModifierProperty(
         defaultConstructor, VisibilityUtil.getVisibilityModifier(aClass.getModifierList()), true);
     addSuperCall(changeInfo, defaultConstructor, null, usages);
   } else {
     final PsiElement parent = aClass.getParent();
     if (parent instanceof PsiNewExpression) {
       final PsiExpressionList argumentList = ((PsiNewExpression) parent).getArgumentList();
       final PsiClass baseClass = changeInfo.getMethod().getContainingClass();
       final PsiSubstitutor substitutor =
           TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY);
       fixActualArgumentsList(argumentList, changeInfo, true, substitutor);
     }
   }
 }
Example #16
0
  public static boolean isNumericType(@Nullable PsiType type) {
    if (type instanceof PsiClassType) {
      return TYPE_TO_RANK.contains(type.getCanonicalText());
    }

    return type instanceof PsiPrimitiveType && TypeConversionUtil.isNumericType(type);
  }
  /* Guesswork
   */
  @Nullable
  private static PsiSubstitutor getInheritorSubstitutorForNewExpression(
      final PsiClass baseClass,
      final PsiClass inheritor,
      final PsiSubstitutor baseSubstitutor,
      final PsiElement context) {
    final Project project = baseClass.getProject();
    JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
    final PsiResolveHelper resolveHelper = facade.getResolveHelper();
    PsiSubstitutor superSubstitutor =
        TypeConversionUtil.getClassSubstitutor(baseClass, inheritor, PsiSubstitutor.EMPTY);
    if (superSubstitutor == null) return null;
    PsiSubstitutor inheritorSubstitutor = PsiSubstitutor.EMPTY;
    for (PsiTypeParameter inheritorParameter : PsiUtil.typeParametersIterable(inheritor)) {
      for (PsiTypeParameter baseParameter : PsiUtil.typeParametersIterable(baseClass)) {
        final PsiType substituted = superSubstitutor.substitute(baseParameter);
        PsiType arg = baseSubstitutor.substitute(baseParameter);
        if (arg instanceof PsiWildcardType) arg = ((PsiWildcardType) arg).getBound();
        PsiType substitution =
            resolveHelper.getSubstitutionForTypeParameter(
                inheritorParameter, substituted, arg, true, PsiUtil.getLanguageLevel(context));
        if (PsiType.NULL.equals(substitution)) continue;
        if (substitution == null) {
          return facade.getElementFactory().createRawSubstitutor(inheritor);
        }
        inheritorSubstitutor = inheritorSubstitutor.put(inheritorParameter, substitution);
        break;
      }
    }

    return inheritorSubstitutor;
  }
  public static void replaceMovedMemberTypeParameters(
      final PsiElement member,
      final Iterable<PsiTypeParameter> parametersIterable,
      final PsiSubstitutor substitutor,
      final GroovyPsiElementFactory factory) {
    final Map<PsiElement, PsiElement> replacement = new LinkedHashMap<PsiElement, PsiElement>();
    for (PsiTypeParameter parameter : parametersIterable) {
      PsiType substitutedType = substitutor.substitute(parameter);
      if (substitutedType == null) {
        substitutedType = TypeConversionUtil.erasure(factory.createType(parameter));
      }

      PsiElement scopeElement = member instanceof GrField ? member.getParent() : member;
      for (PsiReference reference :
          ReferencesSearch.search(parameter, new LocalSearchScope(scopeElement))) {
        final PsiElement element = reference.getElement();
        final PsiElement parent = element.getParent();
        if (parent instanceof PsiTypeElement) {
          replacement.put(parent, factory.createTypeElement(substitutedType));
        } else if (element instanceof GrCodeReferenceElement
            && substitutedType instanceof PsiClassType) {
          replacement.put(
              element, factory.createReferenceElementByType((PsiClassType) substitutedType));
        }
      }
    }

    for (PsiElement element : replacement.keySet()) {
      if (element.isValid()) {
        element.replace(replacement.get(element));
      }
    }
  }
  private static void addInheritors(
      CompletionParameters parameters,
      final CompletionResultSet resultSet,
      final PsiClass referencedClass,
      final int parameterIndex) {
    final List<PsiClassType> typeList =
        Collections.singletonList(
            (PsiClassType)
                TypeConversionUtil.typeParameterErasure(
                    referencedClass.getTypeParameters()[parameterIndex]));
    JavaInheritorsGetter.processInheritors(
        parameters,
        typeList,
        resultSet.getPrefixMatcher(),
        new Consumer<PsiType>() {
          @Override
          public void consume(final PsiType type) {
            final PsiClass psiClass = PsiUtil.resolveClassInType(type);
            if (psiClass == null) return;

            resultSet.addElement(
                TailTypeDecorator.withTail(
                    new JavaPsiClassReferenceElement(psiClass),
                    getTail(parameterIndex == referencedClass.getTypeParameters().length - 1)));
          }
        });
  }
  protected PsiType processLocalVariableInitializer(PsiExpression initializer) {
    PsiType result = null;
    if (null != initializer && !(initializer instanceof PsiArrayInitializerExpression)) {
      if (!recursionBreaker.get().contains(initializer)) {
        recursionBreaker.get().add(initializer);
        try {
          result = initializer.getType();
        } finally {
          recursionBreaker.get().remove(initializer);
        }

        if (initializer instanceof PsiNewExpression) {
          final PsiJavaCodeReferenceElement reference =
              ((PsiNewExpression) initializer).getClassOrAnonymousClassReference();
          if (reference != null) {
            final PsiReferenceParameterList parameterList = reference.getParameterList();
            if (parameterList != null) {
              final PsiTypeElement[] elements = parameterList.getTypeParameterElements();
              if (elements.length == 1 && elements[0].getType() instanceof PsiDiamondType) {
                result = TypeConversionUtil.erasure(result);
              }
            }
          }
        }
      }
    }
    return result;
  }
  public static Set<PsiType> flatten(PsiType[] conjuncts, Set<PsiType> types) {
    for (PsiType conjunct : conjuncts) {
      if (conjunct instanceof PsiIntersectionType) {
        PsiIntersectionType type = (PsiIntersectionType) conjunct;
        flatten(type.getConjuncts(), types);
      } else {
        types.add(conjunct);
      }
    }
    if (types.size() > 1) {
      PsiType[] array = types.toArray(createArray(types.size()));
      for (Iterator<PsiType> iterator = types.iterator(); iterator.hasNext(); ) {
        PsiType type = iterator.next();

        for (PsiType existing : array) {
          if (type != existing) {
            final boolean allowUncheckedConversion =
                type instanceof PsiClassType && ((PsiClassType) type).isRaw();
            if (TypeConversionUtil.isAssignable(type, existing, allowUncheckedConversion)) {
              iterator.remove();
              break;
            }
          }
        }
      }
      if (types.isEmpty()) {
        types.add(array[0]);
      }
    }
    return types;
  }
 private JavaResolveResult advancedResolveImpl() {
   final PsiElement resolve = resolveElement();
   if (resolve instanceof PsiClass) {
     final Map<PsiTypeParameter, PsiType> substitutionMap =
         new HashMap<PsiTypeParameter, PsiType>();
     int index = 0;
     for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable((PsiClass) resolve)) {
       if (index >= myTypeParameters.length) {
         final PsiTypeParameterListOwner parameterOwner = parameter.getOwner();
         if (parameterOwner == resolve) {
           substitutionMap.put(parameter, null);
         } else if (parameterOwner instanceof PsiClass) {
           PsiElement containingClass = myParent;
           while ((containingClass =
                   PsiTreeUtil.getParentOfType(containingClass, PsiClass.class, true))
               != null) {
             final PsiSubstitutor superClassSubstitutor =
                 TypeConversionUtil.getClassSubstitutor(
                     (PsiClass) parameterOwner, (PsiClass) containingClass, PsiSubstitutor.EMPTY);
             if (superClassSubstitutor != null) {
               substitutionMap.put(parameter, superClassSubstitutor.substitute(parameter));
               break;
             }
           }
         }
       } else {
         substitutionMap.put(parameter, myTypeParameters[index].getType());
       }
       index++;
     }
     return new CandidateInfo(resolve, PsiSubstitutorImpl.createSubstitutor(substitutionMap));
   } else {
     return new CandidateInfo(resolve, PsiSubstitutor.EMPTY);
   }
 }
  /**
   * Adds all code methods of clazz add its super classes to signatures. Doesn't walk into
   * interfaces because all methods from them will be overloaded in any case. Besides Some of
   * interfaces came from delegates and they should be visited during the following processing.
   *
   * @param clazz current class
   * @param substitutor super class substitutor of clazz
   * @param signatures map to initialize
   * @param classes already visited classes
   */
  private static void initializeSignatures(
      PsiClass clazz,
      PsiSubstitutor substitutor,
      Map<MethodSignature, PsiMethod> signatures,
      Set<PsiClass> classes) {
    if (clazz.isInterface()) return;

    if (classes.add(clazz)) {
      final List<PsiMethod> methods;
      if (clazz instanceof GrTypeDefinition) {
        methods = new ArrayList<PsiMethod>();
        GrClassImplUtil.collectMethodsFromBody((GrTypeDefinition) clazz, methods);
      } else {
        methods = Arrays.asList(clazz.getMethods());
      }

      for (PsiMethod method : methods) {
        addMethodChecked(signatures, method, substitutor, null);
      }

      for (PsiClassType type : getSuperTypes(clazz)) {
        final PsiClassType.ClassResolveResult result = type.resolveGenerics();
        final PsiClass superClass = result.getElement();
        if (superClass == null) continue;
        final PsiSubstitutor superClassSubstitutor =
            TypeConversionUtil.getSuperClassSubstitutor(superClass, clazz, substitutor);
        initializeSignatures(superClass, superClassSubstitutor, signatures, classes);
      }
    }
  }
  @Nullable
  private PsiAnnotation findNullabilityAnnotation(
      @NotNull PsiModifierListOwner owner, boolean checkBases, boolean nullable) {
    Set<String> qNames = ContainerUtil.newHashSet(nullable ? getNullables() : getNotNulls());
    PsiAnnotation annotation =
        checkBases && (owner instanceof PsiClass || owner instanceof PsiMethod)
            ? AnnotationUtil.findAnnotationInHierarchy(owner, qNames)
            : AnnotationUtil.findAnnotation(owner, qNames);
    if (annotation != null) {
      return annotation;
    }

    if (owner instanceof PsiParameter
        && !TypeConversionUtil.isPrimitiveAndNotNull(((PsiParameter) owner).getType())) {
      // even if javax.annotation.Nullable is not configured, it should still take precedence over
      // ByDefault annotations
      if (AnnotationUtil.isAnnotated(
          owner,
          nullable ? Arrays.asList(DEFAULT_NOT_NULLS) : Arrays.asList(DEFAULT_NULLABLES),
          checkBases,
          false)) {
        return null;
      }
      return findContainerAnnotation(
          owner,
          nullable
              ? "javax.annotation.ParametersAreNullableByDefault"
              : "javax.annotation.ParametersAreNonnullByDefault");
    }
    return null;
  }
 @NotNull
 private static List<PsiMethod> findMethodsBySignature(
     @NotNull PsiClass aClass,
     @NotNull PsiMethod patternMethod,
     boolean checkBases,
     boolean stopOnFirst) {
   final PsiMethod[] methodsByName = aClass.findMethodsByName(patternMethod.getName(), checkBases);
   if (methodsByName.length == 0) return Collections.emptyList();
   final List<PsiMethod> methods = new SmartList<PsiMethod>();
   final MethodSignature patternSignature = patternMethod.getSignature(PsiSubstitutor.EMPTY);
   for (final PsiMethod method : methodsByName) {
     final PsiClass superClass = method.getContainingClass();
     final PsiSubstitutor substitutor;
     if (checkBases && !aClass.equals(superClass)) {
       substitutor =
           TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
     } else {
       substitutor = PsiSubstitutor.EMPTY;
     }
     final MethodSignature signature = method.getSignature(substitutor);
     if (signature.equals(patternSignature)) {
       methods.add(method);
       if (stopOnFirst) {
         break;
       }
     }
   }
   return methods;
 }
Example #26
0
    @Override
    public boolean isMemberEnabled(MemberInfo member) {
      final PsiClass currentSuperClass = getSuperClass();
      if (currentSuperClass == null) return true;
      if (myMemberInfoStorage.getDuplicatedMemberInfos(currentSuperClass).contains(member))
        return false;
      if (myMemberInfoStorage.getExtending(currentSuperClass).contains(member.getMember()))
        return false;
      final boolean isInterface = currentSuperClass.isInterface();
      if (!isInterface) return true;

      PsiElement element = member.getMember();
      if (element instanceof PsiClass && ((PsiClass) element).isInterface()) return true;
      if (element instanceof PsiField) {
        return ((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC);
      }
      if (element instanceof PsiMethod) {
        final PsiSubstitutor superSubstitutor =
            TypeConversionUtil.getSuperClassSubstitutor(
                currentSuperClass, myClass, PsiSubstitutor.EMPTY);
        final MethodSignature signature = ((PsiMethod) element).getSignature(superSubstitutor);
        final PsiMethod superClassMethod =
            MethodSignatureUtil.findMethodBySignature(currentSuperClass, signature, false);
        if (superClassMethod != null && !PsiUtil.isLanguageLevel8OrHigher(currentSuperClass))
          return false;
        return !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC)
            || PsiUtil.isLanguageLevel8OrHigher(currentSuperClass);
      }
      return true;
    }
 private static PsiSubstitutor calculateSubstitutor(
     PsiMethod derivedMethod, PsiMethod baseMethod) {
   PsiSubstitutor substitutor;
   if (derivedMethod.getManager().areElementsEquivalent(derivedMethod, baseMethod)) {
     substitutor = PsiSubstitutor.EMPTY;
   } else {
     final PsiClass baseClass = baseMethod.getContainingClass();
     final PsiClass derivedClass = derivedMethod.getContainingClass();
     if (baseClass != null
         && derivedClass != null
         && InheritanceUtil.isInheritorOrSelf(derivedClass, baseClass, true)) {
       final PsiSubstitutor superClassSubstitutor =
           TypeConversionUtil.getSuperClassSubstitutor(
               baseClass, derivedClass, PsiSubstitutor.EMPTY);
       final MethodSignature superMethodSignature = baseMethod.getSignature(superClassSubstitutor);
       final MethodSignature methodSignature = derivedMethod.getSignature(PsiSubstitutor.EMPTY);
       final PsiSubstitutor superMethodSubstitutor =
           MethodSignatureUtil.getSuperMethodSignatureSubstitutor(
               methodSignature, superMethodSignature);
       substitutor =
           superMethodSubstitutor != null ? superMethodSubstitutor : superClassSubstitutor;
     } else {
       substitutor = PsiSubstitutor.EMPTY;
     }
   }
   return substitutor;
 }
 public void testEnum() throws Exception {
   setupLoadingFilter();
   final PsiClass enumClass =
       myJavaFacade.findClass("enums.OurEnum", GlobalSearchScope.moduleScope(myModule));
   assertNotNull(enumClass);
   assertTrue(enumClass.isEnum());
   final PsiClass superClass = enumClass.getSuperClass();
   assertNotNull(superClass);
   assertEquals("java.lang.Enum", superClass.getQualifiedName());
   assertTrue(enumClass.isInheritor(superClass, false));
   final PsiClassType[] superTypes = enumClass.getSuperTypes();
   assertEquals(1, superTypes.length);
   assertEquals("java.lang.Enum<enums.OurEnum>", superTypes[0].getCanonicalText());
   final PsiClass[] supers = enumClass.getSupers();
   assertEquals(1, supers.length);
   assertEquals("java.lang.Enum", supers[0].getQualifiedName());
   final PsiClassType[] extendsListTypes = enumClass.getExtendsListTypes();
   assertEquals(1, extendsListTypes.length);
   assertEquals("java.lang.Enum<enums.OurEnum>", extendsListTypes[0].getCanonicalText());
   final PsiSubstitutor superClassSubstitutor =
       TypeConversionUtil.getSuperClassSubstitutor(superClass, enumClass, PsiSubstitutor.EMPTY);
   assertEquals(
       "java.lang.Enum<enums.OurEnum>",
       myJavaFacade
           .getElementFactory()
           .createType(superClass, superClassSubstitutor)
           .getCanonicalText());
   teardownLoadingFilter();
 }
  public static String checkReturnType(
      PsiMethodReferenceExpression expression,
      JavaResolveResult result,
      PsiType functionalInterfaceType) {
    final PsiElement resolve = result.getElement();
    if (resolve instanceof PsiMethod) {
      final PsiClass containingClass = ((PsiMethod) resolve).getContainingClass();
      LOG.assertTrue(containingClass != null);
      PsiSubstitutor subst = result.getSubstitutor();
      PsiClass qContainingClass = getQualifierResolveResult(expression).getContainingClass();
      if (qContainingClass != null
          && isReceiverType(functionalInterfaceType, containingClass, (PsiMethod) resolve)) {
        subst = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, subst);
        LOG.assertTrue(subst != null);
      }

      final PsiType interfaceReturnType =
          LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType);

      PsiType returnType =
          PsiTypesUtil.patchMethodGetClassReturnType(
              expression,
              expression,
              (PsiMethod) resolve,
              null,
              PsiUtil.getLanguageLevel(expression));
      if (returnType == null) {
        returnType = ((PsiMethod) resolve).getReturnType();
      }
      PsiType methodReturnType = subst.substitute(returnType);
      if (interfaceReturnType != null && interfaceReturnType != PsiType.VOID) {
        if (methodReturnType == null) {
          methodReturnType =
              JavaPsiFacade.getElementFactory(expression.getProject())
                  .createType(containingClass, subst);
        }
        if (!TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType, false)) {
          return "Bad return type in method reference: cannot convert "
              + methodReturnType.getCanonicalText()
              + " to "
              + interfaceReturnType.getCanonicalText();
        }
      }
    }
    return null;
  }
 @Override
 public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
   return myType.isValid()
       && myExpression.isValid()
       && myExpression.getManager().isInProject(myExpression)
       && !TypeConversionUtil.isPrimitiveAndNotNull(myType)
       && (myType instanceof PsiArrayType || myExpression.getArgumentList() != null);
 }