예제 #1
0
  @NotNull
  private static String[] collectNamesToImport(
      @NotNull PsiJavaFile file, @NotNull Set<String> namesToImportStaticly) {
    Set<String> names = new THashSet<String>();

    final JspFile jspFile = JspPsiUtil.getJspFile(file);
    collectNamesToImport(names, file, namesToImportStaticly, jspFile);
    if (jspFile != null) {
      PsiFile[] files =
          ArrayUtil.mergeArrays(
              JspSpiUtil.getIncludingFiles(jspFile),
              JspSpiUtil.getIncludedFiles(jspFile),
              PsiFile.class);
      for (PsiFile includingFile : files) {
        final PsiFile javaRoot = includingFile.getViewProvider().getPsi(StdLanguages.JAVA);
        if (javaRoot instanceof PsiJavaFile && file != javaRoot) {
          collectNamesToImport(names, (PsiJavaFile) javaRoot, namesToImportStaticly, jspFile);
        }
      }
    }

    addUnresolvedImportNames(names, file, namesToImportStaticly);

    return ArrayUtil.toStringArray(names);
  }
  private static void makeVariableFinalIfNeeded(
      InsertionContext context, @Nullable PsiReferenceExpression ref) {
    if (!Registry.is("java.completion.make.outer.variables.final")
        || ref == null
        || PsiUtil.isLanguageLevel8OrHigher(ref)
        || JspPsiUtil.isInJspFile(ref)) {
      return;
    }

    PsiElement target = ref.resolve();
    if (target instanceof PsiLocalVariable || target instanceof PsiParameter) {
      PsiClass placeClass =
          PsiTreeUtil.findElementOfClassAtOffset(
              context.getFile(), context.getTailOffset() - 1, PsiClass.class, false);
      if (placeClass != null
          && !PsiTreeUtil.isAncestor(placeClass, target, true)
          && !HighlightControlFlowUtil.isReassigned(
              (PsiVariable) target,
              new HashMap<PsiElement, Collection<ControlFlowUtil.VariableInfo>>())) {
        PsiModifierList modifierList = ((PsiVariable) target).getModifierList();
        if (modifierList != null) {
          modifierList.setModifierProperty(PsiModifier.FINAL, true);
        }
      }
    }
  }
  public boolean convertLocalToField(final PsiLocalVariable local, final Editor editor) {
    boolean tempIsStatic = myIsConstant;
    PsiElement parent = local.getParent();
    List<PsiClass> classes = new ArrayList<>();

    if ("gr".equalsIgnoreCase(local.getContainingFile().getVirtualFile().getExtension())) {
      // this is special ij GW studio check for rule files
      CommonRefactoringUtil.showErrorHint(
          myProject,
          editor,
          "Introduce field is not supported for rule files",
          REFACTORING_NAME,
          HelpID.LOCAL_TO_FIELD);
      return false;
    }

    while (parent != null && parent.getContainingFile() != null) {
      if (parent instanceof PsiClass && !(myIsConstant && parent instanceof PsiAnonymousClass)) {
        classes.add((PsiClass) parent);
      }
      if (parent instanceof PsiFile && JspPsiUtil.isInJspFile(parent)) {
        String message = RefactoringBundle.message("error.not.supported.for.jsp", REFACTORING_NAME);
        CommonRefactoringUtil.showErrorHint(
            myProject, editor, message, REFACTORING_NAME, HelpID.LOCAL_TO_FIELD);
        return false;
      }
      if (parent instanceof PsiModifierListOwner
          && ((PsiModifierListOwner) parent).hasModifierProperty(PsiModifier.STATIC)) {
        tempIsStatic = true;
      }
      parent = parent.getParent();
    }

    if (classes.isEmpty()) {
      return false;
    }
    if (classes.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) {
      if (convertLocalToField(
          local, classes.get(getChosenClassIndex(classes)), editor, tempIsStatic)) {
        return false;
      }
    } else {
      final boolean isStatic = tempIsStatic;
      NavigationUtil.getPsiElementPopup(
              classes.toArray(new PsiClass[classes.size()]),
              new PsiClassListCellRenderer(),
              "Choose class to introduce " + (myIsConstant ? "constant" : "field"),
              new PsiElementProcessor<PsiClass>() {
                @Override
                public boolean execute(@NotNull PsiClass aClass) {
                  convertLocalToField(local, aClass, editor, isStatic);
                  return false;
                }
              })
          .showInBestPositionFor(editor);
    }

    return true;
  }
  private static void addReferencesInRange(
      ArrayList<ASTNode> array, TreeElement parent, int startOffset, int endOffset) {
    if (parent.getElementType() == JavaElementType.JAVA_CODE_REFERENCE
        || parent.getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
      array.add(parent);
      return;
    }

    if (parent.getPsi() instanceof PsiFile && JspPsiUtil.isInJspFile(parent.getPsi())) {
      final JspFile jspFile = JspPsiUtil.getJspFile(parent.getPsi());
      JspClass jspClass = (JspClass) jspFile.getJavaClass();
      addReferencesInRange(array, (TreeElement) jspClass.getNode(), startOffset, endOffset);
      return;
    }

    addReferencesInRangeForComposite(array, parent, startOffset, endOffset);
  }
  @Override
  public UsageGroup groupUsage(@NotNull Usage usage) {
    if (!(usage instanceof PsiElementUsage)) {
      return null;
    }
    final PsiElement psiElement = ((PsiElementUsage) usage).getElement();
    final PsiFile containingFile = psiElement.getContainingFile();
    if (containingFile == null) return null;

    PsiFile topLevelFile =
        InjectedLanguageManager.getInstance(containingFile.getProject())
            .getTopLevelFile(containingFile);

    if (!(topLevelFile instanceof PsiJavaFile) || topLevelFile instanceof JspFile) {
      return null;
    }
    PsiElement containingClass =
        topLevelFile == containingFile
            ? psiElement
            : InjectedLanguageManager.getInstance(containingFile.getProject())
                .getInjectionHost(containingFile);
    do {
      containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class, true);
      if (containingClass == null || ((PsiClass) containingClass).getQualifiedName() != null) break;
    } while (true);

    if (containingClass == null) {
      // check whether the element is in the import list
      PsiImportList importList = PsiTreeUtil.getParentOfType(psiElement, PsiImportList.class, true);
      if (importList != null) {
        final String fileName = getFileNameWithoutExtension(topLevelFile);
        final PsiClass[] classes = ((PsiJavaFile) topLevelFile).getClasses();
        for (final PsiClass aClass : classes) {
          if (fileName.equals(aClass.getName())) {
            containingClass = aClass;
            break;
          }
        }
      }
    } else {
      // skip JspClass synthetic classes.
      if (containingClass.getParent() instanceof PsiFile
          && JspPsiUtil.isInJspFile(containingClass)) {
        containingClass = null;
      }
    }

    if (containingClass != null) {
      return new ClassUsageGroup((PsiClass) containingClass);
    }

    final VirtualFile virtualFile = topLevelFile.getVirtualFile();
    if (virtualFile != null) {
      return new FileGroupingRule.FileUsageGroup(topLevelFile.getProject(), virtualFile);
    }
    return null;
  }
 @Override
 public boolean isApplicable(PsiExpression expr) {
   PsiType type = expr.getType();
   if (PsiType.BOOLEAN != type) return false;
   if (!expr.isPhysical()) return false;
   PsiElement parent = expr.getParent();
   if (!(parent instanceof PsiExpressionStatement)) return false;
   final PsiElement element = parent.getParent();
   if (!(element instanceof PsiCodeBlock)
       && !(JspPsiUtil.isInJspFile(element) && element instanceof PsiFile)) return false;
   return true;
 }
 @Override
 public void visitTryStatement(@NotNull PsiTryStatement statement) {
   super.visitTryStatement(statement);
   if (JspPsiUtil.isInJspFile(statement.getContainingFile())) {
     return;
   }
   if (m_ignoreTestCases) {
     if (TestUtils.isPartOfJUnitTestMethod(statement)) {
       return;
     }
     final PsiClass containingClass = PsiTreeUtil.getParentOfType(statement, PsiClass.class);
     if (containingClass != null && TestFrameworks.getInstance().isTestClass(containingClass)) {
       return;
     }
   }
   final PsiCatchSection[] catchSections = statement.getCatchSections();
   for (final PsiCatchSection section : catchSections) {
     checkCatchSection(section);
   }
 }
  private static void addReferencesInRange(
      List<ASTNode> array, ASTNode parent, int startOffset, int endOffset) {
    if (parent.getElementType() == JavaElementType.JAVA_CODE_REFERENCE
        || parent.getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
      array.add(parent);
      return;
    }

    if (parent.getPsi() instanceof PsiFile) {
      JspFile jspFile = JspPsiUtil.getJspFile(parent.getPsi());
      if (jspFile != null) {
        JspClass jspClass = (JspClass) jspFile.getJavaClass();
        if (jspClass != null) {
          addReferencesInRange(array, jspClass.getNode(), startOffset, endOffset);
        }
        return;
      }
    }

    addReferencesInRangeForComposite(array, parent, startOffset, endOffset);
  }
  @Nullable
  public ProblemDescriptor[] checkFile(
      @NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
    // does not work in tests since CodeInsightTestCase copies file into temporary location
    if (ApplicationManager.getApplication().isUnitTestMode()) return null;
    if (file instanceof PsiJavaFile) {
      if (JspPsiUtil.isInJspFile(file)) return null;
      PsiJavaFile javaFile = (PsiJavaFile) file;

      PsiDirectory directory = javaFile.getContainingDirectory();
      if (directory == null) return null;
      PsiPackage dirPackage = JavaDirectoryService.getInstance().getPackage(directory);
      if (dirPackage == null) return null;
      PsiPackageStatement packageStatement = javaFile.getPackageStatement();

      // highlight the first class in the file only
      PsiClass[] classes = javaFile.getClasses();
      if (classes.length == 0 && packageStatement == null) return null;

      String packageName = dirPackage.getQualifiedName();
      if (!Comparing.strEqual(packageName, "", true) && packageStatement == null) {
        String description = JavaErrorMessages.message("missing.package.statement", packageName);

        return new ProblemDescriptor[] {
          manager.createProblemDescriptor(
              classes[0].getNameIdentifier(),
              description,
              new AdjustPackageNameFix(javaFile, null, dirPackage),
              ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
              isOnTheFly)
        };
      }
      if (packageStatement != null) {
        final PsiJavaCodeReferenceElement packageReference = packageStatement.getPackageReference();
        PsiPackage classPackage = (PsiPackage) packageReference.resolve();
        List<LocalQuickFix> availableFixes = new ArrayList<LocalQuickFix>();
        if (classPackage == null) {
          availableFixes.add(new AdjustPackageNameFix(javaFile, packageStatement, dirPackage));
        } else if (!Comparing.equal(
            dirPackage.getQualifiedName(), packageReference.getText(), true)) {
          availableFixes.add(new AdjustPackageNameFix(javaFile, packageStatement, dirPackage));
          MoveToPackageFix moveToPackageFix = new MoveToPackageFix(file, classPackage);
          if (moveToPackageFix.isAvailable()) {
            availableFixes.add(moveToPackageFix);
          }
        }
        if (!availableFixes.isEmpty()) {
          String description =
              JavaErrorMessages.message(
                  "package.name.file.path.mismatch",
                  packageReference.getText(),
                  dirPackage.getQualifiedName());
          return new ProblemDescriptor[] {
            manager.createProblemDescriptor(
                packageStatement.getPackageReference(),
                description,
                isOnTheFly,
                availableFixes.toArray(new LocalQuickFix[availableFixes.size()]),
                ProblemHighlightType.GENERIC_ERROR_OR_WARNING)
          };
        }
      }
    }
    return null;
  }
예제 #10
0
  protected void initialize() {
    myDefaultConstructor = null;

    final PsiClass psiClass = getElement();

    LOG.assertTrue(psiClass != null);

    PsiElement psiParent = psiClass.getParent();
    if (psiParent instanceof PsiFile) {
      if (isSyntheticJSP()) {
        final RefFileImpl refFile =
            (RefFileImpl) getRefManager().getReference(JspPsiUtil.getJspFile(psiClass));
        LOG.assertTrue(refFile != null);
        refFile.add(this);
      } else if (psiParent instanceof PsiJavaFile) {
        PsiJavaFile psiFile = (PsiJavaFile) psiParent;
        String packageName = psiFile.getPackageName();
        if (!"".equals(packageName)) {
          ((RefPackageImpl) getRefJavaManager().getPackage(packageName)).add(this);
        } else {
          ((RefPackageImpl) getRefJavaManager().getDefaultPackage()).add(this);
        }
      }
      final Module module = ModuleUtil.findModuleForPsiElement(psiClass);
      LOG.assertTrue(module != null);
      final RefModuleImpl refModule = ((RefModuleImpl) getRefManager().getRefModule(module));
      LOG.assertTrue(refModule != null);
      refModule.add(this);
    } else {
      while (!(psiParent instanceof PsiClass
          || psiParent instanceof PsiMethod
          || psiParent instanceof PsiField)) {
        psiParent = psiParent.getParent();
      }
      RefElement refParent = getRefManager().getReference(psiParent);
      LOG.assertTrue(refParent != null);
      ((RefElementImpl) refParent).add(this);
    }

    setAbstract(psiClass.hasModifierProperty(PsiModifier.ABSTRACT));

    setAnonymous(psiClass instanceof PsiAnonymousClass);
    setIsLocal(!(isAnonymous() || psiParent instanceof PsiClass || psiParent instanceof PsiFile));
    setInterface(psiClass.isInterface());

    initializeSuperReferences(psiClass);

    PsiMethod[] psiMethods = psiClass.getMethods();
    PsiField[] psiFields = psiClass.getFields();

    setUtilityClass(psiMethods.length > 0 || psiFields.length > 0);

    for (PsiField psiField : psiFields) {
      getRefManager().getReference(psiField);
    }

    if (!isApplet()) {
      final PsiClass servlet = getRefJavaManager().getServlet();
      setServlet(servlet != null && psiClass.isInheritor(servlet, true));
    }
    if (!isApplet() && !isServlet()) {
      setTestCase(TestUtil.isTestClass(psiClass));
      for (RefClass refBase : getBaseClasses()) {
        ((RefClassImpl) refBase).setTestCase(true);
      }
    }

    for (PsiMethod psiMethod : psiMethods) {
      RefMethod refMethod = (RefMethod) getRefManager().getReference(psiMethod);

      if (refMethod != null) {
        if (psiMethod.isConstructor()) {
          if (psiMethod.getParameterList().getParametersCount() > 0
              || !psiMethod.hasModifierProperty(PsiModifier.PRIVATE)) {
            setUtilityClass(false);
          }

          addConstructor(refMethod);
          if (psiMethod.getParameterList().getParametersCount() == 0) {
            setDefaultConstructor((RefMethodImpl) refMethod);
          }
        } else {
          if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
            setUtilityClass(false);
          }
        }
      }
    }

    if (getConstructors().size() == 0 && !isInterface() && !isAnonymous()) {
      RefImplicitConstructorImpl refImplicitConstructor = new RefImplicitConstructorImpl(this);
      setDefaultConstructor(refImplicitConstructor);
      addConstructor(refImplicitConstructor);
    }

    if (isInterface()) {
      for (int i = 0; i < psiFields.length && isUtilityClass(); i++) {
        PsiField psiField = psiFields[i];
        if (!psiField.hasModifierProperty(PsiModifier.STATIC)) {
          setUtilityClass(false);
        }
      }
    }

    final PsiClass applet = getRefJavaManager().getApplet();
    setApplet(applet != null && psiClass.isInheritor(applet, true));
    getRefManager().fireNodeInitialized(this);
  }