private boolean checkCondition(@Nullable PsiExpression condition, @Nullable PsiStatement body) {
   if (body == null) {
     return false;
   }
   if (!(condition instanceof PsiBinaryExpression)) {
     return false;
   }
   final PsiBinaryExpression binaryExpression = (PsiBinaryExpression) condition;
   final IElementType tokenType = binaryExpression.getOperationTokenType();
   final PsiExpression lhs = binaryExpression.getLOperand();
   final PsiExpression rhs = binaryExpression.getROperand();
   if (JavaTokenType.ANDAND == tokenType) {
     return checkCondition(lhs, body) || checkCondition(rhs, body);
   }
   if (JavaTokenType.EQEQ != tokenType) {
     return false;
   }
   if (rhs == null) {
     return false;
   }
   if (PsiUtil.isConstantExpression(lhs)) {
     return checkConstantValueVariableUse(rhs, lhs, body);
   } else if (PsiUtil.isConstantExpression(rhs)) {
     return checkConstantValueVariableUse(lhs, rhs, body);
   }
   return false;
 }
Beispiel #2
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;
    }
  @Override
  protected PsiMethod findOrCreateSetUpMethod(PsiClass clazz) throws IncorrectOperationException {
    LOG.assertTrue(clazz.getLanguage() == GroovyFileType.GROOVY_LANGUAGE);
    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(clazz.getProject());

    final PsiMethod patternMethod = createSetUpPatternMethod(factory);

    final PsiClass baseClass = clazz.getSuperClass();
    if (baseClass != null) {
      final PsiMethod baseMethod = baseClass.findMethodBySignature(patternMethod, false);
      if (baseMethod != null && baseMethod.hasModifierProperty(PsiModifier.PUBLIC)) {
        PsiUtil.setModifierProperty(patternMethod, PsiModifier.PROTECTED, false);
        PsiUtil.setModifierProperty(patternMethod, PsiModifier.PUBLIC, true);
      }
    }

    PsiMethod inClass = clazz.findMethodBySignature(patternMethod, false);
    if (inClass == null) {
      PsiMethod testMethod = JUnitUtil.findFirstTestMethod(clazz);
      if (testMethod != null) {
        return (PsiMethod) clazz.addBefore(patternMethod, testMethod);
      }
      return (PsiMethod) clazz.add(patternMethod);
    } else if (inClass.getBody() == null) {
      return (PsiMethod) inClass.replace(patternMethod);
    }
    return inClass;
  }
 public static boolean isReceiverType(
     PsiType functionalInterfaceType,
     PsiClass containingClass,
     @Nullable PsiMethod referencedMethod) {
   final PsiClassType.ClassResolveResult resolveResult =
       PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
   final MethodSignature function = LambdaUtil.getFunction(resolveResult.getElement());
   if (function != null) {
     final int interfaceMethodParamsLength = function.getParameterTypes().length;
     if (interfaceMethodParamsLength > 0) {
       final PsiType firstParamType =
           resolveResult.getSubstitutor().substitute(function.getParameterTypes()[0]);
       boolean isReceiver =
           isReceiverType(
               firstParamType,
               containingClass,
               PsiUtil.resolveGenericsClassInType(firstParamType).getSubstitutor());
       if (isReceiver) {
         if (referencedMethod == null) {
           if (interfaceMethodParamsLength == 1) return true;
           return false;
         }
         if (referencedMethod.getParameterList().getParametersCount()
             != interfaceMethodParamsLength - 1) {
           return false;
         }
         return true;
       }
     }
   }
   return false;
 }
 @Nullable
 private static PsiType getExpectedTypeArg(
     PsiElement context,
     int index,
     PsiClassType.ClassResolveResult expectedType,
     PsiSubstitutor currentSubstitutor,
     PsiTypeParameter[] params) {
   PsiClass expectedClass = expectedType.getElement();
   assert expectedClass != null;
   for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(expectedClass)) {
     final PsiType argSubstitution = expectedType.getSubstitutor().substitute(parameter);
     final PsiType paramSubstitution = currentSubstitutor.substitute(parameter);
     final PsiType substitution =
         JavaPsiFacade.getInstance(context.getProject())
             .getResolveHelper()
             .getSubstitutionForTypeParameter(
                 params[index],
                 paramSubstitution,
                 argSubstitution,
                 false,
                 PsiUtil.getLanguageLevel(context));
     if (substitution != null && substitution != PsiType.NULL) {
       return substitution;
     }
   }
   return null;
 }
  protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
    final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();

    checkExistingMethods(conflicts, true);
    checkExistingMethods(conflicts, false);
    final Collection<PsiClass> classes = ClassInheritorsSearch.search(myClass).findAll();
    for (FieldDescriptor fieldDescriptor : myFieldDescriptors) {
      final Set<PsiMethod> setters = new HashSet<PsiMethod>();
      final Set<PsiMethod> getters = new HashSet<PsiMethod>();

      for (PsiClass aClass : classes) {
        final PsiMethod getterOverrider =
            myDescriptor.isToEncapsulateGet()
                ? aClass.findMethodBySignature(fieldDescriptor.getGetterPrototype(), false)
                : null;
        if (getterOverrider != null) {
          getters.add(getterOverrider);
        }
        final PsiMethod setterOverrider =
            myDescriptor.isToEncapsulateSet()
                ? aClass.findMethodBySignature(fieldDescriptor.getSetterPrototype(), false)
                : null;
        if (setterOverrider != null) {
          setters.add(setterOverrider);
        }
      }
      if (!getters.isEmpty() || !setters.isEmpty()) {
        final PsiField field = fieldDescriptor.getField();
        for (PsiReference reference : ReferencesSearch.search(field)) {
          final PsiElement place = reference.getElement();
          if (place instanceof PsiReferenceExpression) {
            final PsiExpression qualifierExpression =
                ((PsiReferenceExpression) place).getQualifierExpression();
            final PsiClass ancestor;
            if (qualifierExpression == null) {
              ancestor = PsiTreeUtil.getParentOfType(place, PsiClass.class, false);
            } else {
              ancestor = PsiUtil.resolveClassInType(qualifierExpression.getType());
            }

            final boolean isGetter = !PsiUtil.isAccessedForWriting((PsiExpression) place);
            for (PsiMethod overridden : isGetter ? getters : setters) {
              if (InheritanceUtil.isInheritorOrSelf(myClass, ancestor, true)) {
                conflicts.putValue(
                    overridden,
                    "There is already a "
                        + RefactoringUIUtil.getDescription(overridden, true)
                        + " which would hide generated "
                        + (isGetter ? "getter" : "setter")
                        + " for "
                        + place.getText());
                break;
              }
            }
          }
        }
      }
    }
    return showConflicts(conflicts, refUsages.get());
  }
 @Nullable
 private static PsiClass resolveExtensionPointClass(PsiField psiField) {
   final PsiType typeParameter =
       PsiUtil.substituteTypeParameter(
           psiField.getType(), ExtensionPointName.class.getName(), 0, false);
   return PsiUtil.resolveClassInClassTypeOnly(typeParameter);
 }
 private void doMoveClass(PsiSubstitutor substitutor, MemberInfo info) {
   PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
   PsiClass aClass = (PsiClass) info.getMember();
   if (Boolean.FALSE.equals(info.getOverrides())) {
     final PsiReferenceList sourceReferenceList = info.getSourceReferenceList();
     LOG.assertTrue(sourceReferenceList != null);
     PsiJavaCodeReferenceElement ref =
         mySourceClass.equals(sourceReferenceList.getParent())
             ? RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass)
             : RefactoringUtil.findReferenceToClass(sourceReferenceList, aClass);
     if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) {
       RefactoringUtil.replaceMovedMemberTypeParameters(
           ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
       final PsiReferenceList referenceList =
           myIsTargetInterface
               ? myTargetSuperClass.getExtendsList()
               : myTargetSuperClass.getImplementsList();
       assert referenceList != null;
       referenceList.add(ref);
     }
   } else {
     RefactoringUtil.replaceMovedMemberTypeParameters(
         aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
     fixReferencesToStatic(aClass);
     final PsiMember movedElement =
         (PsiMember)
             myTargetSuperClass.add(
                 convertClassToLanguage(aClass, myTargetSuperClass.getLanguage()));
     myMembersAfterMove.add(movedElement);
     aClass.delete();
   }
 }
 private static void checkSillyAssignment(
     PsiAssignmentExpression assignment, ProblemsHolder holder) {
   if (assignment.getOperationTokenType() != JavaTokenType.EQ) return;
   PsiExpression lExpression = assignment.getLExpression();
   PsiExpression rExpression = assignment.getRExpression();
   if (rExpression == null) return;
   lExpression = PsiUtil.deparenthesizeExpression(lExpression);
   rExpression = PsiUtil.deparenthesizeExpression(rExpression);
   if (!(lExpression instanceof PsiReferenceExpression)) return;
   PsiReferenceExpression rRef;
   if (!(rExpression instanceof PsiReferenceExpression)) {
     if (!(rExpression instanceof PsiAssignmentExpression)) return;
     final PsiAssignmentExpression rAssignmentExpression = (PsiAssignmentExpression) rExpression;
     final PsiExpression assignee =
         PsiUtil.deparenthesizeExpression(rAssignmentExpression.getLExpression());
     if (!(assignee instanceof PsiReferenceExpression)) return;
     rRef = (PsiReferenceExpression) assignee;
   } else {
     rRef = (PsiReferenceExpression) rExpression;
   }
   PsiReferenceExpression lRef = (PsiReferenceExpression) lExpression;
   PsiManager manager = assignment.getManager();
   if (!sameInstanceReferences(lRef, rRef, manager)) return;
   final PsiVariable variable = (PsiVariable) lRef.resolve();
   if (variable == null) return;
   holder.registerProblem(
       assignment,
       InspectionsBundle.message("assignment.to.itself.problem.descriptor", variable.getName()),
       ProblemHighlightType.LIKE_UNUSED_SYMBOL);
 }
  private PsiElement getStatementToInsertBefore() {
    PsiElement declarationScope =
        myVariable instanceof PsiParameter
            ? ((PsiParameter) myVariable).getDeclarationScope()
            : PsiUtil.getVariableCodeBlock(myVariable, null);
    if (declarationScope == null) return null;

    PsiElement statement = myClass;
    nextInnerClass:
    do {
      statement = PsiUtil.getEnclosingStatement(statement);

      if (statement == null || statement.getParent() == null) {
        return null;
      }
      PsiElement element = statement;
      while (element != declarationScope && !(element instanceof PsiFile)) {
        if (element instanceof PsiClass) {
          statement = statement.getParent();
          continue nextInnerClass;
        }
        element = element.getParent();
      }
      return statement;
    } while (true);
  }
 public static void registerQuickFix(
     PsiMember refElement,
     PsiJavaCodeReferenceElement place,
     PsiClass accessObjectClass,
     HighlightInfo error) {
   if (refElement instanceof PsiField && place instanceof PsiReferenceExpression) {
     final PsiField psiField = (PsiField) refElement;
     final PsiClass containingClass = psiField.getContainingClass();
     if (containingClass != null) {
       if (PsiUtil.isOnAssignmentLeftHand((PsiExpression) place)) {
         final PsiMethod setterPrototype = PropertyUtil.generateSetterPrototype(psiField);
         final PsiMethod setter = containingClass.findMethodBySignature(setterPrototype, true);
         if (setter != null && PsiUtil.isAccessible(setter, place, accessObjectClass)) {
           QuickFixAction.registerQuickFixAction(
               error, new ReplaceInaccessibleFieldWithGetterSetterFix(place, setter, true));
         }
       } else if (PsiUtil.isAccessedForReading((PsiExpression) place)) {
         final PsiMethod getterPrototype = PropertyUtil.generateGetterPrototype(psiField);
         final PsiMethod getter = containingClass.findMethodBySignature(getterPrototype, true);
         if (getter != null && PsiUtil.isAccessible(getter, place, accessObjectClass)) {
           QuickFixAction.registerQuickFixAction(
               error, new ReplaceInaccessibleFieldWithGetterSetterFix(place, getter, false));
         }
       }
     }
   }
 }
  /* 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;
  }
    @Override
    public PsiType visitClassType(PsiClassType classType) {
      final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics();
      final PsiClass aClass = resolveResult.getElement();
      if (aClass == null) return classType;

      PsiUtilCore.ensureValid(aClass);
      if (aClass instanceof PsiTypeParameter) {
        final PsiTypeParameter typeParameter = (PsiTypeParameter) aClass;
        if (containsInMap(typeParameter)) {
          PsiType result = substituteTypeParameter(typeParameter);
          if (result != null) {
            PsiUtil.ensureValidType(result);
          }
          return result;
        }
        return classType;
      }
      final Map<PsiTypeParameter, PsiType> hashMap = new HashMap<PsiTypeParameter, PsiType>(2);
      if (!processClass(aClass, resolveResult.getSubstitutor(), hashMap)) {
        return null;
      }
      PsiClassType result =
          JavaPsiFacade.getElementFactory(aClass.getProject())
              .createType(aClass, createSubstitutor(hashMap), classType.getLanguageLevel());
      PsiUtil.ensureValidType(result);
      return result;
    }
  private static boolean isCollectCall(PsiStatement body, final PsiParameter parameter) {
    PsiIfStatement ifStatement = extractIfStatement(body);
    final PsiMethodCallExpression methodCallExpression = extractAddCall(body, ifStatement);
    if (methodCallExpression != null) {
      final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
      final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
      PsiClass qualifierClass = null;
      if (qualifierExpression instanceof PsiReferenceExpression) {
        if (ReferencesSearch.search(parameter, new LocalSearchScope(qualifierExpression))
                .findFirst()
            != null) {
          return false;
        }
        final PsiElement resolve = ((PsiReferenceExpression) qualifierExpression).resolve();
        if (resolve instanceof PsiVariable) {
          if (ReferencesSearch.search(
                      resolve, new LocalSearchScope(methodCallExpression.getArgumentList()))
                  .findFirst()
              != null) {
            return false;
          }
        }
        qualifierClass = PsiUtil.resolveClassInType(qualifierExpression.getType());
      } else if (qualifierExpression == null) {
        final PsiClass enclosingClass = PsiTreeUtil.getParentOfType(body, PsiClass.class);
        if (PsiUtil.getEnclosingStaticElement(body, enclosingClass) == null) {
          qualifierClass = enclosingClass;
        }
      }

      if (qualifierClass != null
          && InheritanceUtil.isInheritor(
              qualifierClass, false, CommonClassNames.JAVA_UTIL_COLLECTION)) {

        while (ifStatement != null && PsiTreeUtil.isAncestor(body, ifStatement, false)) {
          final PsiExpression condition = ifStatement.getCondition();
          if (condition != null
              && isConditionDependsOnUpdatedCollections(condition, qualifierExpression))
            return false;
          ifStatement = PsiTreeUtil.getParentOfType(ifStatement, PsiIfStatement.class);
        }

        final PsiElement resolve = methodExpression.resolve();
        if (resolve instanceof PsiMethod
            && "add".equals(((PsiMethod) resolve).getName())
            && ((PsiMethod) resolve).getParameterList().getParametersCount() == 1) {
          final PsiExpression[] args = methodCallExpression.getArgumentList().getExpressions();
          if (args.length == 1) {
            if (args[0] instanceof PsiCallExpression) {
              final PsiMethod method = ((PsiCallExpression) args[0]).resolveMethod();
              return method != null && !method.hasTypeParameters() && !isThrowsCompatible(method);
            }
            return true;
          }
        }
      }
    }
    return false;
  }
Beispiel #15
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;
  }
Beispiel #16
0
  public static void checkMethodConflicts(
      @Nullable PsiClass aClass,
      PsiMethod refactoredMethod,
      PsiMethod prototype,
      final MultiMap<PsiElement, String> conflicts) {
    if (prototype == null) return;

    PsiMethod method = aClass != null ? aClass.findMethodBySignature(prototype, true) : null;

    if (method != null && method != refactoredMethod) {
      if (aClass.equals(method.getContainingClass())) {
        final String classDescr =
            aClass instanceof PsiAnonymousClass
                ? RefactoringBundle.message("current.class")
                : RefactoringUIUtil.getDescription(aClass, false);
        conflicts.putValue(
            method,
            RefactoringBundle.message(
                "method.0.is.already.defined.in.the.1",
                getMethodPrototypeString(prototype),
                classDescr));
      } else { // method somewhere in base class
        if (JavaPsiFacade.getInstance(method.getProject())
            .getResolveHelper()
            .isAccessible(method, aClass, null)) {
          String protoMethodInfo = getMethodPrototypeString(prototype);
          String className =
              CommonRefactoringUtil.htmlEmphasize(
                  UsageViewUtil.getDescriptiveName(method.getContainingClass()));
          if (PsiUtil.getAccessLevel(prototype.getModifierList())
              >= PsiUtil.getAccessLevel(method.getModifierList())) {
            boolean isMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
            boolean isMyMethodAbstract =
                refactoredMethod != null
                    && refactoredMethod.hasModifierProperty(PsiModifier.ABSTRACT);
            final String conflict =
                isMethodAbstract != isMyMethodAbstract
                    ? RefactoringBundle.message(
                        "method.0.will.implement.method.of.the.base.class",
                        protoMethodInfo,
                        className)
                    : RefactoringBundle.message(
                        "method.0.will.override.a.method.of.the.base.class",
                        protoMethodInfo,
                        className);
            conflicts.putValue(method, conflict);
          } else { // prototype is private, will be compile-error
            conflicts.putValue(
                method,
                RefactoringBundle.message(
                    "method.0.will.hide.method.of.the.base.class", protoMethodInfo, className));
          }
        }
      }
    }
  }
  private void doMoveClass(PsiSubstitutor substitutor, GrMemberInfo info) {
    GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
    GrTypeDefinition aClass = (GrTypeDefinition) info.getMember();
    if (Boolean.FALSE.equals(info.getOverrides())) {
      final GrReferenceList sourceReferenceList = info.getSourceReferenceList();
      LOG.assertTrue(sourceReferenceList != null);
      GrCodeReferenceElement ref =
          mySourceClass.equals(sourceReferenceList.getParent())
              ? removeFromReferenceList(sourceReferenceList, aClass)
              : findReferenceToClass(sourceReferenceList, aClass);
      if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) {
        replaceMovedMemberTypeParameters(
            ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
        GrReferenceList referenceList;
        if (myTargetSuperClass.isInterface()) {
          referenceList = myTargetSuperClass.getExtendsClause();
          if (referenceList == null) {
            GrExtendsClause newClause =
                GroovyPsiElementFactory.getInstance(myProject).createExtendsClause();
            PsiElement anchor =
                myTargetSuperClass.getTypeParameterList() != null
                    ? myTargetSuperClass.getTypeParameterList()
                    : myTargetSuperClass.getNameIdentifierGroovy();
            referenceList = (GrReferenceList) myTargetSuperClass.addAfter(newClause, anchor);
            addSpacesAround(referenceList);
          }
        } else {
          referenceList = myTargetSuperClass.getImplementsClause();

          if (referenceList == null) {
            GrImplementsClause newClause =
                GroovyPsiElementFactory.getInstance(myProject).createImplementsClause();
            PsiElement anchor =
                myTargetSuperClass.getExtendsClause() != null
                    ? myTargetSuperClass.getExtendsClause()
                    : myTargetSuperClass.getTypeParameterList() != null
                        ? myTargetSuperClass.getTypeParameterList()
                        : myTargetSuperClass.getNameIdentifierGroovy();
            referenceList = (GrReferenceList) myTargetSuperClass.addAfter(newClause, anchor);
            addSpacesAround(referenceList);
          }
        }

        assert referenceList != null;
        referenceList.add(ref);
      }
    } else {
      replaceMovedMemberTypeParameters(
          aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
      // fixReferencesToStatic(aClass, movedMembers);
      PsiMember movedElement = (PsiMember) myTargetSuperClass.addAfter(aClass, null);
      // movedElement = (PsiMember)CodeStyleManager.getInstance(myProject).reformat(movedElement);
      myMembersAfterMove.add(movedElement);
      deleteMemberWithDocComment(aClass);
    }
  }
  private static PsiType genNewMapBy(PsiType genericOwner, PsiManager manager) {
    PsiClass map =
        JavaPsiFacade.getInstance(manager.getProject())
            .findClass(JAVA_UTIL_MAP, genericOwner.getResolveScope());
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(manager.getProject());
    if (map == null) return factory.createTypeFromText(JAVA_UTIL_MAP, null);

    final PsiType key = PsiUtil.substituteTypeParameter(genericOwner, JAVA_UTIL_MAP, 0, false);
    final PsiType value = PsiUtil.substituteTypeParameter(genericOwner, JAVA_UTIL_MAP, 1, false);
    return factory.createType(map, key, value);
  }
  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 void doMoveField(PsiSubstitutor substitutor, GrMemberInfo info) {
   GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
   GrField field = (GrField) info.getMember();
   field.normalizeDeclaration();
   replaceMovedMemberTypeParameters(
       field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
   // fixReferencesToStatic(field, movedMembers);
   if (myTargetSuperClass.isInterface()) {
     PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true);
   }
   final PsiMember movedElement = (PsiMember) myTargetSuperClass.add(field);
   myMembersAfterMove.add(movedElement);
   deleteMemberWithDocComment(field);
 }
    @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());
    }
  public static PsiType normalizeWildcardTypeByPosition(
      @NotNull PsiType type, @NotNull PsiExpression expression) {
    PsiExpression toplevel = expression;
    while (toplevel.getParent() instanceof PsiArrayAccessExpression
        && ((PsiArrayAccessExpression) toplevel.getParent()).getArrayExpression() == toplevel) {
      toplevel = (PsiExpression) toplevel.getParent();
    }

    final PsiType normalized = doNormalizeWildcardByPosition(type, expression, toplevel);
    if (normalized instanceof PsiClassType && !PsiUtil.isAccessedForWriting(toplevel)) {
      return PsiUtil.captureToplevelWildcards(normalized, expression);
    }

    return normalized;
  }
  /**
   * Allows to check if static import may be performed for the given element.
   *
   * @param element element to check
   * @return target class that may be statically imported if any; <code>null</code> otherwise
   */
  @Nullable
  public static PsiClass getClassToPerformStaticImport(@NotNull PsiElement element) {
    if (!PsiUtil.isLanguageLevel5OrHigher(element)) return null;
    if (!(element instanceof PsiIdentifier)
        || !(element.getParent() instanceof PsiJavaCodeReferenceElement)) {
      return null;
    }
    PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement) element.getParent();
    if (refExpr instanceof PsiMethodReferenceExpression) return null;
    final PsiElement gParent = refExpr.getParent();
    if (gParent instanceof PsiMethodReferenceExpression) return null;
    if (!(gParent instanceof PsiJavaCodeReferenceElement)
        || isParameterizedReference((PsiJavaCodeReferenceElement) gParent)) return null;

    PsiElement resolved = refExpr.resolve();
    if (!(resolved instanceof PsiClass)) {
      return null;
    }
    PsiClass psiClass = (PsiClass) resolved;
    if (PsiUtil.isFromDefaultPackage(psiClass)
        || psiClass.hasModifierProperty(PsiModifier.PRIVATE)
        || psiClass.getQualifiedName() == null) return null;

    final PsiElement ggParent = gParent.getParent();
    if (ggParent instanceof PsiMethodCallExpression) {
      final PsiMethodCallExpression call = (PsiMethodCallExpression) ggParent.copy();
      final PsiElement qualifier = call.getMethodExpression().getQualifier();
      if (qualifier == null) return null;
      qualifier.delete();
      final PsiMethod method = call.resolveMethod();
      if (method != null && method.getContainingClass() != psiClass) return null;
    } else {
      final PsiJavaCodeReferenceElement copy = (PsiJavaCodeReferenceElement) gParent.copy();
      final PsiElement qualifier = copy.getQualifier();
      if (qualifier == null) return null;
      qualifier.delete();
      final PsiElement target = copy.resolve();
      if (target != null && PsiTreeUtil.getParentOfType(target, PsiClass.class) != psiClass)
        return null;
    }

    PsiFile file = refExpr.getContainingFile();
    if (!(file instanceof PsiJavaFile)) return null;
    PsiImportList importList = ((PsiJavaFile) file).getImportList();
    if (importList == null) return null;

    return psiClass;
  }
  private static void addStatementKeywords(Consumer<LookupElement> variant, PsiElement position) {
    variant.consume(
        new OverrideableSpace(
            createKeyword(position, PsiKeyword.SWITCH), TailTypes.SWITCH_LPARENTH));
    variant.consume(
        new OverrideableSpace(createKeyword(position, PsiKeyword.WHILE), TailTypes.WHILE_LPARENTH));
    variant.consume(
        new OverrideableSpace(createKeyword(position, PsiKeyword.DO), TailTypes.DO_LBRACE));
    variant.consume(
        new OverrideableSpace(createKeyword(position, PsiKeyword.FOR), TailTypes.FOR_LPARENTH));
    variant.consume(
        new OverrideableSpace(createKeyword(position, PsiKeyword.IF), TailTypes.IF_LPARENTH));
    variant.consume(
        new OverrideableSpace(createKeyword(position, PsiKeyword.TRY), TailTypes.TRY_LBRACE));
    variant.consume(
        new OverrideableSpace(createKeyword(position, PsiKeyword.THROW), TailType.INSERT_SPACE));
    variant.consume(
        new OverrideableSpace(createKeyword(position, PsiKeyword.NEW), TailType.INSERT_SPACE));
    variant.consume(
        new OverrideableSpace(
            createKeyword(position, PsiKeyword.SYNCHRONIZED), TailTypes.SYNCHRONIZED_LPARENTH));

    if (PsiUtil.getLanguageLevel(position).isAtLeast(LanguageLevel.JDK_1_4)) {
      variant.consume(
          new OverrideableSpace(createKeyword(position, PsiKeyword.ASSERT), TailType.INSERT_SPACE));
    }

    TailType returnTail = getReturnTail(position);
    LookupElement ret = createKeyword(position, PsiKeyword.RETURN);
    if (returnTail != TailType.NONE) {
      ret = new OverrideableSpace(ret, returnTail);
    }
    variant.consume(ret);
  }
 @Override
 public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
   super.visitMethodCallExpression(expression);
   final PsiExpressionList argumentList = expression.getArgumentList();
   final PsiExpression[] arguments = argumentList.getExpressions();
   if (arguments.length == 0) {
     return;
   }
   final PsiExpression xpathArgument = arguments[0];
   if (!ExpressionUtils.hasStringType(xpathArgument)) {
     return;
   }
   if (!PsiUtil.isConstantExpression(xpathArgument)) {
     return;
   }
   final PsiType type = xpathArgument.getType();
   if (type == null) {
     return;
   }
   final String value = (String) ConstantExpressionUtil.computeCastTo(xpathArgument, type);
   if (value == null) {
     return;
   }
   if (!callTakesXPathExpression(expression)) {
     return;
   }
   final XPathFactory xpathFactory = XPathFactory.newInstance();
   final XPath xpath = xpathFactory.newXPath();
   //noinspection UnusedCatchParameter,ProhibitedExceptionCaught
   try {
     xpath.compile(value);
   } catch (XPathExpressionException ignore) {
     registerError(xpathArgument);
   }
 }
  private static int getQuickFixType(PsiVariable variable) {
    PsiElement outerCodeBlock = PsiUtil.getVariableCodeBlock(variable, null);
    if (outerCodeBlock == null) return -1;
    List<PsiReferenceExpression> outerReferences = new ArrayList<PsiReferenceExpression>();
    collectReferences(outerCodeBlock, variable, outerReferences);

    int type = MAKE_FINAL;
    for (PsiReferenceExpression expression : outerReferences) {
      // if it happens that variable referenced from another inner class, make sure it can be make
      // final from there
      PsiClass innerClass =
          HighlightControlFlowUtil.getInnerClassVariableReferencedFrom(variable, expression);

      if (innerClass != null) {
        int thisType = MAKE_FINAL;
        if (writtenInside(variable, innerClass)) {
          // cannot make parameter array
          if (variable instanceof PsiParameter) return -1;
          thisType = MAKE_ARRAY;
        }
        if (thisType == MAKE_FINAL && !canBeFinal(variable, outerReferences)) {
          thisType = COPY_TO_FINAL;
        }
        type = Math.max(type, thisType);
      }
    }
    return type;
  }
 private void makeFinal() {
   for (PsiVariable var : getVariablesToFix()) {
     if (var.isValid()) {
       PsiUtil.setModifierProperty(var, PsiModifier.FINAL, true);
     }
   }
 }
 @Nullable
 private static PsiClass getFieldOrMethodAccessedClass(
     PsiReferenceExpression ref, PsiClass fieldOrMethodClass) {
   PsiElement[] children = ref.getChildren();
   if (children.length > 1 && children[0] instanceof PsiExpression) {
     PsiExpression expr = (PsiExpression) children[0];
     PsiType type = expr.getType();
     if (type != null) {
       if (!(type instanceof PsiClassType)) return null;
       return PsiUtil.resolveClassInType(type);
     } else {
       if (expr instanceof PsiReferenceExpression) {
         PsiElement refElement = ((PsiReferenceExpression) expr).resolve();
         if (refElement instanceof PsiClass) return (PsiClass) refElement;
       }
       return null;
     }
   }
   PsiManager manager = ref.getManager();
   for (PsiElement parent = ref; parent != null; parent = parent.getParent()) {
     if (parent instanceof PsiClass
         && (manager.areElementsEquivalent(parent, fieldOrMethodClass)
             || ((PsiClass) parent).isInheritor(fieldOrMethodClass, true))) {
       return (PsiClass) parent;
     }
   }
   return null;
 }
 @Nullable
 private static PsiClass findClass(PsiNewExpression newExpression) {
   final PsiJavaCodeReferenceElement classReference =
       newExpression.getClassOrAnonymousClassReference();
   if (classReference != null) {
     final String text = classReference.getReferenceName();
     if (text != null) {
       final Project project = newExpression.getProject();
       final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
       final PsiResolveHelper resolveHelper = facade.getResolveHelper();
       final PsiExpression newExpressionQualifier = newExpression.getQualifier();
       final PsiElement qualifierElement = classReference.getQualifier();
       final String qualifier = qualifierElement != null ? qualifierElement.getText() : "";
       final String qualifiedName = StringUtil.getQualifiedName(qualifier, text);
       if (newExpressionQualifier != null) {
         final PsiClass aClass =
             PsiUtil.resolveClassInClassTypeOnly(newExpressionQualifier.getType());
         if (aClass != null) {
           return aClass.findInnerClassByName(qualifiedName, false);
         }
       }
       return resolveHelper.resolveReferencedClass(qualifiedName, newExpression);
     } else {
       return null;
     }
   }
   return null;
 }
    @Override
    public void visitBinaryExpression(GrBinaryExpression expression) {
      super.visitBinaryExpression(expression);

      if (expression.getOperationTokenType() != GroovyTokenTypes.kIN) return;

      GrExpression leftOperand = expression.getLeftOperand();
      GrExpression rightOperand = expression.getRightOperand();
      if (leftOperand == null || rightOperand == null) return;

      PsiType ltype = leftOperand.getType();
      PsiType rtype = rightOperand.getType();
      if (ltype == null || rtype == null) return;

      PsiType component;

      if (rtype instanceof PsiArrayType) {
        component = ((PsiArrayType) rtype).getComponentType();
      } else if (InheritanceUtil.isInheritor(rtype, CommonClassNames.JAVA_UTIL_COLLECTION)) {
        component =
            PsiUtil.substituteTypeParameter(rtype, CommonClassNames.JAVA_UTIL_COLLECTION, 0, false);
      } else {
        checkSimpleClasses(ltype, rtype, expression);
        return;
      }

      if (component == null) return;

      if (TypesUtil.isAssignable(
          ltype, component, expression.getManager(), expression.getResolveScope(), false)) return;

      registerError(expression, ltype, rtype);
    }