public void invoke(
     @NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
   editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
   final int offset =
       TargetElementUtil.adjustOffset(
           file, editor.getDocument(), editor.getCaretModel().getOffset());
   final PsiElement element = file.findElementAt(offset);
   PsiTypeElement typeElement = PsiTreeUtil.getParentOfType(element, PsiTypeElement.class);
   while (typeElement != null) {
     final PsiElement parent = typeElement.getParent();
     PsiElement[] toMigrate = null;
     if (parent instanceof PsiVariable) {
       toMigrate = extractReferencedVariables(typeElement);
     } else if ((parent instanceof PsiMember && !(parent instanceof PsiClass))
         || isClassArgument(parent)) {
       toMigrate = new PsiElement[] {parent};
     }
     if (toMigrate != null && toMigrate.length > 0) {
       invoke(project, toMigrate, null, null, editor);
       return;
     }
     typeElement = PsiTreeUtil.getParentOfType(parent, PsiTypeElement.class, false);
   }
   CommonRefactoringUtil.showErrorHint(
       project,
       editor,
       "The caret should be positioned on type of field, variable, method or method parameter to be refactored",
       REFACTORING_NAME,
       "refactoring.migrateType");
 }
 private static void checkMethodReference(
     PsiMethodReferenceExpression expression,
     InspectionManager inspectionManager,
     List<ProblemDescriptor> problems) {
   final PsiTypeElement qualifierTypeElement = expression.getQualifierType();
   if (qualifierTypeElement != null) {
     final PsiType psiType = qualifierTypeElement.getType();
     if (psiType instanceof PsiClassType && !(((PsiClassType) psiType).isRaw())) {
       final JavaResolveResult result = expression.advancedResolve(false);
       final PsiElement element = result.getElement();
       if (element instanceof PsiTypeParameterListOwner) {
         final PsiMethodReferenceExpression copy =
             createMethodReference(expression, qualifierTypeElement);
         final JavaResolveResult simplifiedResolve = copy.advancedResolve(false);
         final PsiElement candidate = simplifiedResolve.getElement();
         if (candidate == element) {
           final PsiJavaCodeReferenceElement referenceElement =
               qualifierTypeElement.getInnermostComponentReferenceElement();
           LOG.assertTrue(referenceElement != null, qualifierTypeElement);
           final PsiReferenceParameterList parameterList = referenceElement.getParameterList();
           LOG.assertTrue(parameterList != null);
           final ProblemDescriptor descriptor =
               inspectionManager.createProblemDescriptor(
                   parameterList,
                   InspectionsBundle.message("inspection.redundant.type.problem.descriptor"),
                   new MyMethodReferenceFixAction(),
                   ProblemHighlightType.LIKE_UNUSED_SYMBOL,
                   false);
           problems.add(descriptor);
         }
       }
     }
   }
 }
  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;
  }
 private static boolean typeElementsAreEquivalent(
     PsiTypeElement typeElement1, PsiTypeElement typeElement2) {
   if (typeElement1 == null) {
     return typeElement2 == null;
   } else if (typeElement2 == null) {
     return false;
   }
   final PsiType type1 = typeElement1.getType();
   final PsiType type2 = typeElement2.getType();
   return typesAreEquivalent(type1, type2);
 }
 @Override
 protected void doFix(Project project, ProblemDescriptor descriptor) {
   final PsiElement element = descriptor.getPsiElement();
   if (!(element instanceof PsiTypeElement)) {
     return;
   }
   final PsiTypeElement typeElement = (PsiTypeElement) element;
   final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
   final PsiClassType type =
       factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION);
   final PsiTypeElement newTypeElement = factory.createTypeElement(type);
   typeElement.replace(newTypeElement);
 }
  @Nullable
  public static List<String> findTestDataFiles(@NotNull DataContext context) {
    final PsiMethod method = findTargetMethod(context);
    if (method == null) {
      return null;
    }
    final String name = method.getName();

    if (name.startsWith("test")) {
      String testDataPath =
          TestDataLineMarkerProvider.getTestDataBasePath(method.getContainingClass());
      final TestDataReferenceCollector collector =
          new TestDataReferenceCollector(testDataPath, name.substring(4));
      return collector.collectTestDataReferences(method);
    }

    final Location<?> location = Location.DATA_KEY.getData(context);
    if (location instanceof PsiMemberParameterizedLocation) {
      PsiClass containingClass = ((PsiMemberParameterizedLocation) location).getContainingClass();
      if (containingClass == null) {
        containingClass =
            PsiTreeUtil.getParentOfType(location.getPsiElement(), PsiClass.class, false);
      }
      if (containingClass != null) {
        final PsiAnnotation annotation =
            AnnotationUtil.findAnnotationInHierarchy(
                containingClass, Collections.singleton(JUnitUtil.RUN_WITH));
        if (annotation != null) {
          final PsiAnnotationMemberValue memberValue = annotation.findAttributeValue("value");
          if (memberValue instanceof PsiClassObjectAccessExpression) {
            final PsiTypeElement operand =
                ((PsiClassObjectAccessExpression) memberValue).getOperand();
            if (operand.getType().equalsToText(Parameterized.class.getName())) {
              final String testDataPath =
                  TestDataLineMarkerProvider.getTestDataBasePath(containingClass);
              final String paramSetName =
                  ((PsiMemberParameterizedLocation) location).getParamSetName();
              final String baseFileName =
                  StringUtil.trimEnd(StringUtil.trimStart(paramSetName, "["), "]");
              final ProjectFileIndex fileIndex =
                  ProjectRootManager.getInstance(containingClass.getProject()).getFileIndex();
              return TestDataGuessByExistingFilesUtil.suggestTestDataFiles(
                  fileIndex, baseFileName, testDataPath, containingClass);
            }
          }
        }
      }
    }

    return null;
  }
 @Override
 protected final void doFix(Project project, ProblemDescriptor descriptor)
     throws IncorrectOperationException {
   final PsiElement element = descriptor.getPsiElement();
   final PsiTypeElement castTypeElement;
   final PsiReferenceExpression reference;
   if (element instanceof PsiTypeCastExpression) {
     final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression) element;
     castTypeElement = typeCastExpression.getCastType();
     final PsiExpression operand = typeCastExpression.getOperand();
     if (!(operand instanceof PsiReferenceExpression)) {
       return;
     }
     reference = (PsiReferenceExpression) operand;
   } else if (element instanceof PsiMethodCallExpression) {
     final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) element;
     final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
     final PsiExpression qualifier = methodExpression.getQualifierExpression();
     if (!(qualifier instanceof PsiClassObjectAccessExpression)) {
       return;
     }
     final PsiClassObjectAccessExpression classObjectAccessExpression =
         (PsiClassObjectAccessExpression) qualifier;
     castTypeElement = classObjectAccessExpression.getOperand();
     final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
     final PsiExpression[] arguments = argumentList.getExpressions();
     if (arguments.length != 1) {
       return;
     }
     final PsiExpression argument = arguments[0];
     if (!(argument instanceof PsiReferenceExpression)) {
       return;
     }
     reference = (PsiReferenceExpression) argument;
   } else {
     return;
   }
   if (castTypeElement == null) {
     return;
   }
   final PsiInstanceOfExpression conflictingInstanceof =
       InstanceOfUtils.getConflictingInstanceof(castTypeElement.getType(), reference, element);
   final PsiTypeElement instanceofTypeElement = conflictingInstanceof.getCheckType();
   if (instanceofTypeElement == null) {
     return;
   }
   final PsiElement newElement = replace(castTypeElement, instanceofTypeElement);
   final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
   codeStyleManager.shortenClassReferences(newElement);
 }
 @Override
 public void visitMethodCallExpression(PsiMethodCallExpression expression) {
   super.visitMethodCallExpression(expression);
   final PsiReferenceExpression methodExpression = expression.getMethodExpression();
   final String methodName = methodExpression.getReferenceName();
   if (!"cast".equals(methodName)) {
     return;
   }
   final PsiMethod method = expression.resolveMethod();
   if (method == null) {
     return;
   }
   final PsiClass containingClass = method.getContainingClass();
   if (containingClass == null) {
     return;
   }
   final String qualifiedName = containingClass.getQualifiedName();
   if (!"java.lang.Class".equals(qualifiedName)) {
     return;
   }
   final PsiExpression qualifier = methodExpression.getQualifierExpression();
   if (!(qualifier instanceof PsiClassObjectAccessExpression)) {
     return;
   }
   final PsiClassObjectAccessExpression classObjectAccessExpression =
       (PsiClassObjectAccessExpression) qualifier;
   final PsiTypeElement operand = classObjectAccessExpression.getOperand();
   final PsiType castType = operand.getType();
   if (!(castType instanceof PsiClassType)) {
     return;
   }
   final PsiExpressionList argumentList = expression.getArgumentList();
   final PsiExpression[] arguments = argumentList.getExpressions();
   if (arguments.length != 1) {
     return;
   }
   final PsiExpression argument = arguments[0];
   if (!(argument instanceof PsiReferenceExpression)) {
     return;
   }
   final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) argument;
   final PsiInstanceOfExpression conflictingInstanceof =
       InstanceOfUtils.getConflictingInstanceof(castType, referenceExpression, expression);
   if (conflictingInstanceof == null) {
     return;
   }
   final PsiTypeElement instanceofTypeElement = conflictingInstanceof.getCheckType();
   registerError(expression, referenceExpression, operand, instanceofTypeElement);
 }
Пример #9
0
 public static PsiClass getProviderClass(final PsiElement element, final PsiClass topLevelClass) {
   final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(element, PsiAnnotation.class);
   if (annotation != null) {
     final PsiAnnotationMemberValue value =
         annotation.findDeclaredAttributeValue("dataProviderClass");
     if (value instanceof PsiClassObjectAccessExpression) {
       final PsiTypeElement operand = ((PsiClassObjectAccessExpression) value).getOperand();
       final PsiClass psiClass = PsiUtil.resolveClassInType(operand.getType());
       if (psiClass != null) {
         return psiClass;
       }
     }
   }
   return topLevelClass;
 }
 @NotNull
 private static PsiElement[] extractReferencedVariables(@NotNull PsiTypeElement typeElement) {
   final PsiElement parent = typeElement.getParent();
   if (parent instanceof PsiVariable) {
     if (parent instanceof PsiField) {
       PsiField aField = (PsiField) parent;
       List<PsiField> fields = new ArrayList<>();
       while (true) {
         fields.add(aField);
         aField = PsiTreeUtil.getNextSiblingOfType(aField, PsiField.class);
         if (aField == null || aField.getTypeElement() != typeElement) {
           return fields.toArray(new PsiElement[fields.size()]);
         }
       }
     } else if (parent instanceof PsiLocalVariable) {
       final PsiDeclarationStatement declaration =
           PsiTreeUtil.getParentOfType(parent, PsiDeclarationStatement.class);
       if (declaration != null) {
         return Arrays.stream(declaration.getDeclaredElements())
             .filter(PsiVariable.class::isInstance)
             .toArray(PsiVariable[]::new);
       }
     }
     return new PsiElement[] {parent};
   } else {
     return PsiElement.EMPTY_ARRAY;
   }
 }
Пример #11
0
 private static boolean instanceofExpressionsAreEquivalent(
     PsiInstanceOfExpression instanceOfExpression1,
     PsiInstanceOfExpression instanceOfExpression2) {
   final PsiExpression operand1 = instanceOfExpression1.getOperand();
   final PsiExpression operand2 = instanceOfExpression2.getOperand();
   if (!expressionsAreEquivalent(operand1, operand2)) {
     return false;
   }
   final PsiTypeElement typeElement1 = instanceOfExpression1.getCheckType();
   final PsiTypeElement typeElement2 = instanceOfExpression2.getCheckType();
   if (typeElement1 == null) {
     return typeElement2 == null;
   } else if (typeElement2 == null) {
     return false;
   }
   final PsiType type1 = typeElement1.getType();
   final PsiType type2 = typeElement2.getType();
   return typesAreEquivalent(type1, type2);
 }
 private static PsiMethodReferenceExpression createMethodReference(
     PsiMethodReferenceExpression expression, PsiTypeElement typeElement) {
   final PsiType type = typeElement.getType();
   final PsiElementFactory elementFactory =
       JavaPsiFacade.getElementFactory(expression.getProject());
   final PsiMethodReferenceExpression copy = (PsiMethodReferenceExpression) expression.copy();
   copy.getQualifierType()
       .replace(elementFactory.createTypeElement(((PsiClassType) type).rawType()));
   return copy;
 }
Пример #13
0
 private static boolean typecastExpressionsAreEquivalent(
     @NotNull PsiTypeCastExpression typecastExp1, @NotNull PsiTypeCastExpression typecastExp2) {
   final PsiTypeElement typeElement1 = typecastExp1.getCastType();
   final PsiTypeElement typeElement2 = typecastExp2.getCastType();
   if (typeElement1 == null && typeElement2 == null) {
     return true;
   }
   if (typeElement1 == null || typeElement2 == null) {
     return false;
   }
   final PsiType type1 = typeElement1.getType();
   final PsiType type2 = typeElement2.getType();
   if (!typesAreEquivalent(type1, type2)) {
     return false;
   }
   final PsiExpression operand1 = typecastExp1.getOperand();
   final PsiExpression operand2 = typecastExp2.getOperand();
   return expressionsAreEquivalent(operand1, operand2);
 }
 @Nullable
 public static HighlightInfo checkValidAnnotationType(final PsiTypeElement typeElement) {
   PsiType type = typeElement.getType();
   if (type.accept(AnnotationReturnTypeVisitor.INSTANCE).booleanValue()) {
     return null;
   }
   String description = JavaErrorMessages.message("annotation.invalid.annotation.member.type");
   return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
       .range(typeElement)
       .descriptionAndTooltip(description)
       .create();
 }
 @Override
 public void visitReferenceParameterList(PsiReferenceParameterList referenceParameterList) {
   super.visitReferenceParameterList(referenceParameterList);
   final PsiTypeElement[] typeParameterElements =
       referenceParameterList.getTypeParameterElements();
   if (typeParameterElements.length == 1) {
     final PsiTypeElement typeParameterElement = typeParameterElements[0];
     final PsiType type = typeParameterElement.getType();
     if (type instanceof PsiDiamondType) {
       final PsiNewExpression newExpression =
           PsiTreeUtil.getParentOfType(referenceParameterList, PsiNewExpression.class);
       if (newExpression != null) {
         final List<PsiType> types =
             PsiDiamondTypeImpl.resolveInferredTypesNoCheck(newExpression, newExpression)
                 .getInferredTypes();
         if (!types.isEmpty()) {
           registerError(referenceParameterList);
         }
       }
     }
   }
 }
 @Nullable
 public static HighlightInfo checkCyclicMemberType(PsiTypeElement typeElement, PsiClass aClass) {
   LOG.assertTrue(aClass.isAnnotationType());
   PsiType type = typeElement.getType();
   final Set<PsiClass> checked = new HashSet<PsiClass>();
   if (cyclicDependencies(aClass, type, checked, aClass.getManager())) {
     String description = JavaErrorMessages.message("annotation.cyclic.element.type");
     return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
         .range(typeElement)
         .descriptionAndTooltip(description)
         .create();
   }
   return null;
 }
 @Nullable
 public static PsiType getQualifierType(PsiMethodReferenceExpression expression) {
   PsiType qualifierType = null;
   final PsiTypeElement typeElement = expression.getQualifierType();
   if (typeElement != null) {
     qualifierType = typeElement.getType();
   } else {
     final PsiElement qualifier = expression.getQualifier();
     if (qualifier instanceof PsiExpression) {
       qualifierType = ((PsiExpression) qualifier).getType();
     }
   }
   if (qualifierType == null) {
     final QualifierResolveResult qualifierResolveResult = getQualifierResolveResult(expression);
     final PsiClass containingClass = qualifierResolveResult.getContainingClass();
     if (containingClass == null) {
       return null;
     }
     qualifierType =
         JavaPsiFacade.getElementFactory(expression.getProject()).createType(containingClass);
   }
   return qualifierType;
 }
 @NotNull
 public static QualifierResolveResult getQualifierResolveResult(
     @NotNull PsiMethodReferenceExpression methodReferenceExpression) {
   PsiClass containingClass = null;
   PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
   final PsiExpression expression = methodReferenceExpression.getQualifierExpression();
   if (expression != null) {
     final PsiType expressionType = getExpandedType(expression.getType(), expression);
     PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(expressionType);
     containingClass = result.getElement();
     if (containingClass != null) {
       substitutor = result.getSubstitutor();
     }
     if (containingClass == null && expression instanceof PsiReferenceExpression) {
       final JavaResolveResult resolveResult =
           ((PsiReferenceExpression) expression).advancedResolve(false);
       final PsiElement resolve = resolveResult.getElement();
       if (resolve instanceof PsiClass) {
         containingClass = (PsiClass) resolve;
         substitutor = resolveResult.getSubstitutor();
         return new QualifierResolveResult(containingClass, substitutor, true);
       }
     }
   } else {
     final PsiTypeElement typeElement = methodReferenceExpression.getQualifierType();
     if (typeElement != null) {
       PsiType type = getExpandedType(typeElement.getType(), typeElement);
       PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type);
       containingClass = result.getElement();
       if (containingClass != null) {
         return new QualifierResolveResult(containingClass, result.getSubstitutor(), true);
       }
     }
   }
   return new QualifierResolveResult(containingClass, substitutor, false);
 }
 public static String checkTypeArguments(PsiTypeElement qualifier, PsiType psiType) {
   if (psiType instanceof PsiClassType) {
     final PsiJavaCodeReferenceElement referenceElement =
         qualifier.getInnermostComponentReferenceElement();
     if (referenceElement != null) {
       PsiType[] typeParameters = referenceElement.getTypeParameters();
       for (PsiType typeParameter : typeParameters) {
         if (typeParameter instanceof PsiWildcardType) {
           return "Unexpected wildcard";
         }
       }
     }
   }
   return null;
 }
 @Override
 public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) {
   super.visitTypeCastExpression(expression);
   final PsiTypeElement castType = expression.getCastType();
   if (castType == null) {
     return;
   }
   final PsiType type = castType.getType();
   final PsiExpression operand = expression.getOperand();
   if (!(operand instanceof PsiReferenceExpression)) {
     return;
   }
   final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) operand;
   final PsiInstanceOfExpression conflictingInstanceof =
       InstanceOfUtils.getConflictingInstanceof(type, referenceExpression, expression);
   if (conflictingInstanceof == null) {
     return;
   }
   final PsiTypeElement instanceofTypeElement = conflictingInstanceof.getCheckType();
   if (instanceofTypeElement == null) {
     return;
   }
   registerError(expression, referenceExpression, castType, instanceofTypeElement);
 }
  public void setupTypeElement(
      PsiTypeElement typeElement,
      ExpectedTypeInfo[] infos,
      PsiSubstitutor substitutor,
      TemplateBuilder builder,
      @Nullable PsiElement context,
      PsiClass targetClass) {
    LOG.assertTrue(typeElement.isValid());
    ApplicationManager.getApplication().assertWriteAccessAllowed();

    PsiManager manager = typeElement.getManager();
    GlobalSearchScope scope = typeElement.getResolveScope();
    Project project = manager.getProject();

    if (infos.length == 1 && substitutor != null && substitutor != PsiSubstitutor.EMPTY) {
      ExpectedTypeInfo info = infos[0];
      Map<PsiTypeParameter, PsiType> map = substitutor.getSubstitutionMap();
      PsiType[] vals = map.values().toArray(PsiType.createArray(map.size()));
      PsiTypeParameter[] params = map.keySet().toArray(new PsiTypeParameter[map.size()]);

      List<PsiType> types = matchingTypeParameters(vals, params, info);
      if (!types.isEmpty()) {
        ContainerUtil.addAll(
            types,
            ExpectedTypesProvider.processExpectedTypes(
                infos, new MyTypeVisitor(manager, scope), project));
        builder.replaceElement(
            typeElement,
            new TypeExpression(project, types.toArray(PsiType.createArray(types.size()))));
        return;
      } else {
        PsiElementFactory factory =
            JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
        PsiType type = info.getType();
        PsiType defaultType = info.getDefaultType();
        try {
          PsiTypeElement inplaceTypeElement =
              ((PsiVariable)
                      factory.createVariableDeclarationStatement("foo", type, null)
                          .getDeclaredElements()[0])
                  .getTypeElement();

          PsiSubstitutor rawingSubstitutor = getRawingSubstitutor(context, targetClass);
          int substitionResult =
              substituteToTypeParameters(
                  typeElement, inplaceTypeElement, vals, params, builder, rawingSubstitutor, true);
          if (substitionResult != SUBSTITUTED_NONE) {
            if (substitionResult == SUBSTITUTED_IN_PARAMETERS) {
              PsiJavaCodeReferenceElement refElement =
                  typeElement.getInnermostComponentReferenceElement();
              LOG.assertTrue(refElement != null && refElement.getReferenceNameElement() != null);
              type = getComponentType(type);
              LOG.assertTrue(type != null);
              defaultType = getComponentType(defaultType);
              LOG.assertTrue(defaultType != null);
              ExpectedTypeInfo info1 =
                  ExpectedTypesProvider.createInfo(
                      ((PsiClassType) defaultType).rawType(),
                      ExpectedTypeInfo.TYPE_STRICTLY,
                      ((PsiClassType) defaultType).rawType(),
                      info.getTailType());
              MyTypeVisitor visitor = new MyTypeVisitor(manager, scope);
              builder.replaceElement(
                  refElement.getReferenceNameElement(),
                  new TypeExpression(
                      project,
                      ExpectedTypesProvider.processExpectedTypes(
                          new ExpectedTypeInfo[] {info1}, visitor, project)));
            }

            return;
          }
        } catch (IncorrectOperationException e) {
          LOG.error(e);
        }
      }
    }

    PsiType[] types =
        infos.length == 0
            ? new PsiType[] {typeElement.getType()}
            : ExpectedTypesProvider.processExpectedTypes(
                infos, new MyTypeVisitor(manager, scope), project);
    builder.replaceElement(typeElement, new TypeExpression(project, types));
  }
 @Override
 protected PsiElement replace(
     PsiTypeElement castTypeElement, PsiTypeElement instanceofTypeElement) {
   return instanceofTypeElement.replace(castTypeElement);
 }
  @Nullable
  public static HighlightInfo checkApplicability(
      @NotNull PsiAnnotation annotation,
      @NotNull LanguageLevel languageLevel,
      @NotNull PsiFile containingFile) {
    if (ANY_ANNOTATION_ALLOWED.accepts(annotation)) {
      return null;
    }

    PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
    if (nameRef == null) return null;

    PsiAnnotationOwner owner = annotation.getOwner();
    PsiAnnotation.TargetType[] targets = PsiImplUtil.getTargetsForLocation(owner);
    if (owner == null || targets.length == 0) {
      String message = JavaErrorMessages.message("annotation.not.allowed.here");
      return annotationError(annotation, message);
    }

    if (!(owner instanceof PsiModifierList)) {
      HighlightInfo info =
          HighlightUtil.checkTypeAnnotationFeature(annotation, languageLevel, containingFile);
      if (info != null) return info;
    }

    PsiAnnotation.TargetType applicable = PsiImplUtil.findApplicableTarget(annotation, targets);
    if (applicable == PsiAnnotation.TargetType.UNKNOWN) return null;

    if (applicable == null) {
      String target = JavaErrorMessages.message("annotation.target." + targets[0]);
      String message =
          JavaErrorMessages.message("annotation.not.applicable", nameRef.getText(), target);
      return annotationError(annotation, message);
    }

    if (applicable == PsiAnnotation.TargetType.TYPE_USE) {
      if (owner instanceof PsiClassReferenceType) {
        PsiJavaCodeReferenceElement ref = ((PsiClassReferenceType) owner).getReference();
        HighlightInfo info = checkReferenceTarget(annotation, ref);
        if (info != null) return info;
      } else if (owner instanceof PsiModifierList) {
        PsiElement nextElement =
            PsiTreeUtil.skipSiblingsForward(
                (PsiModifierList) owner,
                PsiComment.class,
                PsiWhiteSpace.class,
                PsiTypeParameterList.class);
        if (nextElement instanceof PsiTypeElement) {
          PsiTypeElement typeElement = (PsiTypeElement) nextElement;
          PsiType type = typeElement.getType();
          if (PsiType.VOID.equals(type)) {
            String message = JavaErrorMessages.message("annotation.not.allowed.void");
            return annotationError(annotation, message);
          }
          if (!(type instanceof PsiPrimitiveType)) {
            PsiJavaCodeReferenceElement ref =
                getOutermostReferenceElement(typeElement.getInnermostComponentReferenceElement());
            HighlightInfo info = checkReferenceTarget(annotation, ref);
            if (info != null) return info;
          }
        }
      } else if (owner instanceof PsiTypeElement) {
        PsiElement context =
            PsiTreeUtil.skipParentsOfType((PsiTypeElement) owner, PsiTypeElement.class);
        if (context instanceof PsiClassObjectAccessExpression) {
          String message = JavaErrorMessages.message("annotation.not.allowed.class");
          return annotationError(annotation, message);
        }
      }
    }

    return null;
  }
 @Override
 public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
   super.visitClassObjectAccessExpression(expression);
   PsiElement parent = expression.getParent();
   if (parent instanceof PsiReferenceExpression) {
     final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) parent;
     if (!expression.equals(referenceExpression.getQualifierExpression())) {
       return;
     }
     @NonNls final String name = referenceExpression.getReferenceName();
     if (!"getName".equals(name)) {
       return;
     }
     final PsiElement grandParent = referenceExpression.getParent();
     if (!(grandParent instanceof PsiMethodCallExpression)) {
       return;
     }
     final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) grandParent;
     final PsiExpressionList list = methodCallExpression.getArgumentList();
     if (list.getExpressions().length != 0) {
       return;
     }
     parent = methodCallExpression.getParent();
   }
   if (!(parent instanceof PsiExpressionList)) {
     return;
   }
   final PsiElement grandParent = parent.getParent();
   if (!(grandParent instanceof PsiMethodCallExpression)) {
     return;
   }
   final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) grandParent;
   final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
   final PsiExpression[] expressions = argumentList.getExpressions();
   if (expressions.length != 1) {
     return;
   }
   final PsiClass containingClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
   if (containingClass == null) {
     return;
   }
   final String containingClassName = containingClass.getName();
   if (containingClassName == null) {
     return;
   }
   final PsiMethod method = methodCallExpression.resolveMethod();
   if (method == null) {
     return;
   }
   final PsiClass aClass = method.getContainingClass();
   if (aClass == null) {
     return;
   }
   final String className = aClass.getQualifiedName();
   final int index = loggerFactoryClassNames.indexOf(className);
   if (index < 0) {
     return;
   }
   final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
   final String referenceName = methodExpression.getReferenceName();
   final String loggerFactoryMethodName = loggerFactoryMethodNames.get(index);
   if (!loggerFactoryMethodName.equals(referenceName)) {
     return;
   }
   final PsiTypeElement operand = expression.getOperand();
   final PsiType type = operand.getType();
   if (!(type instanceof PsiClassType)) {
     return;
   }
   final PsiClassType classType = (PsiClassType) type;
   final PsiClass initializerClass = classType.resolve();
   if (initializerClass == null) {
     return;
   }
   if (containingClass.equals(initializerClass)) {
     return;
   }
   registerError(expression, containingClassName);
 }
  private static void processPrimaryMethod(
      JavaChangeInfo changeInfo, PsiMethod method, PsiMethod baseMethod, boolean isOriginal)
      throws IncorrectOperationException {
    PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();

    if (changeInfo.isVisibilityChanged()) {
      PsiModifierList modifierList = method.getModifierList();
      final String highestVisibility =
          isOriginal
              ? changeInfo.getNewVisibility()
              : VisibilityUtil.getHighestVisibility(
                  changeInfo.getNewVisibility(),
                  VisibilityUtil.getVisibilityModifier(modifierList));
      VisibilityUtil.setVisibility(modifierList, highestVisibility);
    }

    if (changeInfo.isNameChanged()) {
      String newName =
          baseMethod == null
              ? changeInfo.getNewName()
              : RefactoringUtil.suggestNewOverriderName(
                  method.getName(), baseMethod.getName(), changeInfo.getNewName());

      if (newName != null && !newName.equals(method.getName())) {
        final PsiIdentifier nameId = method.getNameIdentifier();
        assert nameId != null;
        nameId.replace(
            JavaPsiFacade.getInstance(method.getProject())
                .getElementFactory()
                .createIdentifier(newName));
      }
    }

    final PsiSubstitutor substitutor =
        baseMethod == null
            ? PsiSubstitutor.EMPTY
            : ChangeSignatureProcessor.calculateSubstitutor(method, baseMethod);

    if (changeInfo.isReturnTypeChanged()) {
      PsiType newTypeElement =
          changeInfo
              .getNewReturnType()
              .getType(changeInfo.getMethod().getParameterList(), method.getManager());
      final PsiType returnType = substitutor.substitute(newTypeElement);
      // don't modify return type for non-Java overriders (EJB)
      if (method.getName().equals(changeInfo.getNewName())) {
        final PsiTypeElement typeElement = method.getReturnTypeElement();
        if (typeElement != null) {
          typeElement.replace(factory.createTypeElement(returnType));
        }
      }
    }

    PsiParameterList list = method.getParameterList();
    PsiParameter[] parameters = list.getParameters();

    final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters();
    final int delta =
        baseMethod != null
            ? baseMethod.getParameterList().getParametersCount()
                - method.getParameterList().getParametersCount()
            : 0;
    PsiParameter[] newParms = new PsiParameter[Math.max(parameterInfos.length - delta, 0)];
    final String[] oldParameterNames = changeInfo.getOldParameterNames();
    final String[] oldParameterTypes = changeInfo.getOldParameterTypes();
    for (int i = 0; i < newParms.length; i++) {
      JavaParameterInfo info = parameterInfos[i];
      int index = info.getOldIndex();
      if (index >= 0) {
        PsiParameter parameter = parameters[index];
        newParms[i] = parameter;

        String oldName = oldParameterNames[index];
        if (!oldName.equals(info.getName()) && oldName.equals(parameter.getName())) {
          PsiIdentifier newIdentifier = factory.createIdentifier(info.getName());
          parameter.getNameIdentifier().replace(newIdentifier);
        }

        String oldType = oldParameterTypes[index];
        if (!oldType.equals(info.getTypeText())) {
          parameter.normalizeDeclaration();
          PsiType newType =
              substitutor.substitute(
                  info.createType(changeInfo.getMethod().getParameterList(), method.getManager()));

          parameter.getTypeElement().replace(factory.createTypeElement(newType));
        }
      } else {
        newParms[i] = createNewParameter(changeInfo, info, substitutor);
      }
    }

    resolveParameterVsFieldsConflicts(newParms, method, list, changeInfo.toRemoveParm());
    fixJavadocsForChangedMethod(method, changeInfo, newParms.length);
    if (changeInfo.isExceptionSetOrOrderChanged()) {
      final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo);
      fixPrimaryThrowsLists(method, newExceptions);
    }
  }
Пример #26
0
 private static boolean textMatches(@Nullable PsiTypeElement typeElement, @NotNull String text) {
   return typeElement != null && typeElement.textMatches(text);
 }
Пример #27
0
  @Override
  public void beforeCompletion(@NotNull final CompletionInitializationContext context) {
    final PsiFile file = context.getFile();

    if (file instanceof PsiJavaFile) {
      if (context.getInvocationCount() > 0) {
        autoImport(file, context.getStartOffset() - 1, context.getEditor());

        PsiElement leaf = file.findElementAt(context.getStartOffset() - 1);
        if (leaf != null) leaf = PsiTreeUtil.prevVisibleLeaf(leaf);

        PsiVariable variable = PsiTreeUtil.getParentOfType(leaf, PsiVariable.class);
        if (variable != null) {
          PsiTypeElement typeElement = variable.getTypeElement();
          if (typeElement != null) {
            PsiType type = typeElement.getType();
            if (type instanceof PsiClassType && ((PsiClassType) type).resolve() == null) {
              autoImportReference(
                  file, context.getEditor(), typeElement.getInnermostComponentReferenceElement());
            }
          }
        }
      }

      JavaCompletionUtil.initOffsets(file, context.getOffsetMap());

      if (context.getCompletionType() == CompletionType.BASIC) {
        if (semicolonNeeded(context.getEditor(), file, context.getStartOffset())) {
          context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER.trim() + ";");
          return;
        }

        final PsiJavaCodeReferenceElement ref =
            PsiTreeUtil.findElementOfClassAtOffset(
                file, context.getStartOffset(), PsiJavaCodeReferenceElement.class, false);
        if (ref != null && !(ref instanceof PsiReferenceExpression)) {
          if (ref.getParent() instanceof PsiTypeElement) {
            context.setDummyIdentifier(
                CompletionInitializationContext.DUMMY_IDENTIFIER.trim() + ";");
          }

          if (JavaSmartCompletionContributor.AFTER_NEW.accepts(ref)) {
            final PsiReferenceParameterList paramList = ref.getParameterList();
            if (paramList != null && paramList.getTextLength() > 0) {
              context
                  .getOffsetMap()
                  .addOffset(
                      ConstructorInsertHandler.PARAM_LIST_START,
                      paramList.getTextRange().getStartOffset());
              context
                  .getOffsetMap()
                  .addOffset(
                      ConstructorInsertHandler.PARAM_LIST_END,
                      paramList.getTextRange().getEndOffset());
            }
          }

          return;
        }

        final PsiElement element = file.findElementAt(context.getStartOffset());

        if (psiElement().inside(PsiAnnotation.class).accepts(element)) {
          return;
        }

        context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED);
      }
    }
  }
Пример #28
0
  @Override
  public ASTNode process(
      @NotNull ASTNode element,
      boolean addImports,
      boolean incompleteCode,
      boolean useFqInJavadoc,
      boolean useFqInCode) {
    IElementType elementType = element.getElementType();
    if ((elementType == JavaElementType.JAVA_CODE_REFERENCE
            || elementType == JavaElementType.REFERENCE_EXPRESSION)
        && !isAnnotated(element)) {
      IElementType parentType = element.getTreeParent().getElementType();
      if (elementType == JavaElementType.JAVA_CODE_REFERENCE
          || incompleteCode
          || parentType == JavaElementType.REFERENCE_EXPRESSION
          || parentType == JavaElementType.METHOD_REF_EXPRESSION) {
        PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) element.getPsi();

        PsiReferenceParameterList parameterList = ref.getParameterList();
        if (parameterList != null) {
          PsiTypeElement[] typeParameters = parameterList.getTypeParameterElements();
          for (PsiTypeElement typeParameter : typeParameters) {
            process(
                typeParameter.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
          }
        }

        boolean rightKind = true;
        if (elementType == JavaElementType.JAVA_CODE_REFERENCE) {
          PsiJavaCodeReferenceElementImpl impl = (PsiJavaCodeReferenceElementImpl) element;
          int kind = impl.getKind(impl.getContainingFile());
          rightKind =
              kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND
                  || kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND;
        }

        if (rightKind) {
          // annotations may jump out of reference (see PsiJavaCodeReferenceImpl#setAnnotations())
          // so they should be processed first
          List<PsiAnnotation> annotations =
              PsiTreeUtil.getChildrenOfTypeAsList(ref, PsiAnnotation.class);
          for (PsiAnnotation annotation : annotations) {
            process(annotation.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
          }

          boolean isInsideDocComment =
              TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null;
          boolean isShort = !ref.isQualified();
          if (isInsideDocComment ? !useFqInJavadoc : !useFqInCode) {
            if (isShort) return element; // short name already, no need to change
          }

          PsiElement refElement;
          if (!incompleteCode) {
            refElement = ref.resolve();
          } else {
            PsiResolveHelper helper =
                JavaPsiFacade.getInstance(ref.getManager().getProject()).getResolveHelper();
            final SourceJavaCodeReference reference = (SourceJavaCodeReference) element;
            refElement = helper.resolveReferencedClass(reference.getClassNameText(), ref);
          }

          if (refElement instanceof PsiClass) {
            PsiClass psiClass = (PsiClass) refElement;
            if (isInsideDocComment ? useFqInJavadoc : useFqInCode) {
              String qName = psiClass.getQualifiedName();
              if (qName == null) return element;

              PsiFile file = ref.getContainingFile();
              if (file instanceof PsiJavaFile) {
                if (ImportHelper.isImplicitlyImported(qName, (PsiJavaFile) file)) {
                  if (isShort) return element;
                  return makeShortReference((CompositeElement) element, psiClass, addImports);
                }

                String thisPackageName = ((PsiJavaFile) file).getPackageName();
                if (ImportHelper.hasPackage(qName, thisPackageName)) {
                  if (!isShort) {
                    return makeShortReference((CompositeElement) element, psiClass, addImports);
                  }
                }
              }

              return replaceReferenceWithFQ(element, psiClass);
            } else {
              int oldLength = element.getTextLength();
              ASTNode treeElement =
                  makeShortReference((CompositeElement) element, psiClass, addImports);
              if (treeElement.getTextLength() == oldLength
                  && psiClass.getContainingClass() != null) {
                PsiElement qualifier = ref.getQualifier();
                if (qualifier instanceof PsiJavaCodeReferenceElement
                    && ((PsiJavaCodeReferenceElement) qualifier).resolve() instanceof PsiClass) {
                  process(
                      qualifier.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
                }
              }
              return treeElement;
            }
          }
        }
      }
    }

    for (ASTNode child = element.getFirstChildNode(); child != null; child = child.getTreeNext()) {
      //noinspection AssignmentToForLoopParameter
      child = process(child, addImports, incompleteCode, useFqInJavadoc, useFqInCode);
    }

    return element;
  }
Пример #29
0
  public static boolean isAcceptable(
      PsiLambdaExpression lambdaExpression, final PsiType leftType, boolean checkReturnType) {
    if (leftType instanceof PsiIntersectionType) {
      for (PsiType conjunctType : ((PsiIntersectionType) leftType).getConjuncts()) {
        if (isAcceptable(lambdaExpression, conjunctType, checkReturnType)) return true;
      }
      return false;
    }
    final PsiClassType.ClassResolveResult resolveResult =
        PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(leftType));
    final PsiClass psiClass = resolveResult.getElement();
    if (psiClass instanceof PsiAnonymousClass) {
      return isAcceptable(
          lambdaExpression, ((PsiAnonymousClass) psiClass).getBaseClassType(), checkReturnType);
    }
    final MethodSignature methodSignature = getFunction(psiClass);
    if (methodSignature == null) return false;
    final PsiParameter[] lambdaParameters = lambdaExpression.getParameterList().getParameters();
    final PsiType[] parameterTypes = methodSignature.getParameterTypes();
    if (lambdaParameters.length != parameterTypes.length) return false;
    for (int lambdaParamIdx = 0, length = lambdaParameters.length;
        lambdaParamIdx < length;
        lambdaParamIdx++) {
      PsiParameter parameter = lambdaParameters[lambdaParamIdx];
      final PsiTypeElement typeElement = parameter.getTypeElement();
      if (typeElement != null) {
        final PsiType lambdaFormalType = typeElement.getType();
        final PsiType methodParameterType = parameterTypes[lambdaParamIdx];
        if (lambdaFormalType instanceof PsiPrimitiveType) {
          if (methodParameterType instanceof PsiPrimitiveType)
            return methodParameterType.equals(lambdaFormalType);
          return false;
        }

        if (!TypeConversionUtil.erasure(lambdaFormalType)
            .isAssignableFrom(
                TypeConversionUtil.erasure(
                    GenericsUtil.eliminateWildcards(
                        resolveResult
                            .getSubstitutor()
                            .substitute(
                                methodSignature
                                    .getSubstitutor()
                                    .substitute(methodParameterType)))))) {
          return false;
        }
      }
    }
    if (checkReturnType) {
      final String uniqueVarName =
          JavaCodeStyleManager.getInstance(lambdaExpression.getProject())
              .suggestUniqueVariableName("l", lambdaExpression, true);
      String canonicalText = leftType.getCanonicalText();
      if (leftType instanceof PsiEllipsisType) {
        canonicalText = ((PsiEllipsisType) leftType).toArrayType().getCanonicalText();
      }
      final PsiStatement assignmentFromText =
          JavaPsiFacade.getElementFactory(lambdaExpression.getProject())
              .createStatementFromText(
                  canonicalText + " " + uniqueVarName + " = " + lambdaExpression.getText(),
                  lambdaExpression);
      final PsiLocalVariable localVariable =
          (PsiLocalVariable)
              ((PsiDeclarationStatement) assignmentFromText).getDeclaredElements()[0];
      LOG.assertTrue(psiClass != null);
      PsiType methodReturnType = getReturnType(psiClass, methodSignature);
      if (methodReturnType != null) {
        methodReturnType =
            resolveResult
                .getSubstitutor()
                .substitute(methodSignature.getSubstitutor().substitute(methodReturnType));
        return LambdaHighlightingUtil.checkReturnTypeCompatible(
                (PsiLambdaExpression) localVariable.getInitializer(), methodReturnType)
            == null;
      }
    }
    return true;
  }