public static boolean addStaticImport( @NotNull String qualifierClass, @NonNls @NotNull String memberName, @NotNull PsiElement context) { if (!nameCanBeStaticallyImported(qualifierClass, memberName, context)) { return false; } final PsiClass containingClass = PsiTreeUtil.getParentOfType(context, PsiClass.class); if (InheritanceUtil.isInheritor(containingClass, qualifierClass)) { return true; } final PsiFile psiFile = context.getContainingFile(); if (!(psiFile instanceof PsiJavaFile)) { return false; } final PsiJavaFile javaFile = (PsiJavaFile) psiFile; final PsiImportList importList = javaFile.getImportList(); if (importList == null) { return false; } final PsiImportStatementBase existingImportStatement = importList.findSingleImportStatement(memberName); if (existingImportStatement != null) { return false; } final PsiImportStaticStatement onDemandImportStatement = findOnDemandImportStaticStatement(importList, qualifierClass); if (onDemandImportStatement != null && !hasOnDemandImportStaticConflict(qualifierClass, memberName, context)) { return true; } final Project project = context.getProject(); final GlobalSearchScope scope = context.getResolveScope(); final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final PsiClass aClass = psiFacade.findClass(qualifierClass, scope); if (aClass == null) { return false; } final String qualifiedName = aClass.getQualifiedName(); if (qualifiedName == null) { return false; } final List<PsiImportStaticStatement> imports = getMatchingImports(importList, qualifiedName); final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); final PsiElementFactory elementFactory = psiFacade.getElementFactory(); if (imports.size() < codeStyleSettings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND) { importList.add(elementFactory.createImportStaticStatement(aClass, memberName)); } else { for (PsiImportStaticStatement importStatement : imports) { importStatement.delete(); } importList.add(elementFactory.createImportStaticStatement(aClass, "*")); } return true; }
private static List<PsiImportStaticStatement> getMatchingImports( @NotNull PsiImportList importList, @NotNull String className) { final List<PsiImportStaticStatement> imports = new ArrayList(); for (PsiImportStaticStatement staticStatement : importList.getImportStaticStatements()) { final PsiClass psiClass = staticStatement.resolveTargetClass(); if (psiClass == null) { continue; } if (!className.equals(psiClass.getQualifiedName())) { continue; } imports.add(staticStatement); } return imports; }
@Nullable private static PsiImportStaticStatement findOnDemandImportStaticStatement( PsiImportList importList, String qualifierClass) { final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements(); for (PsiImportStaticStatement importStaticStatement : importStaticStatements) { if (!importStaticStatement.isOnDemand()) { continue; } final PsiJavaCodeReferenceElement importReference = importStaticStatement.getImportReference(); if (importReference == null) { continue; } final String text = importReference.getText(); if (qualifierClass.equals(text)) { return importStaticStatement; } } return null; }
private static boolean hasExactImportStaticConflict( String qualifierClass, String memberName, PsiElement context) { final PsiFile file = context.getContainingFile(); if (!(file instanceof PsiJavaFile)) { return false; } final PsiJavaFile javaFile = (PsiJavaFile) file; final PsiImportList importList = javaFile.getImportList(); if (importList == null) { return false; } final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements(); for (PsiImportStaticStatement importStaticStatement : importStaticStatements) { if (importStaticStatement.isOnDemand()) { continue; } final String name = importStaticStatement.getReferenceName(); if (!memberName.equals(name)) { continue; } final PsiJavaCodeReferenceElement importReference = importStaticStatement.getImportReference(); if (importReference == null) { continue; } final PsiElement qualifier = importReference.getQualifier(); if (qualifier == null) { continue; } final String qualifierText = qualifier.getText(); if (!qualifierClass.equals(qualifierText)) { return true; } } return false; }
private static boolean hasOnDemandImportStaticConflict( String fqName, String memberName, PsiElement context, boolean strict) { final PsiFile file = context.getContainingFile(); if (!(file instanceof PsiJavaFile)) { return false; } final PsiJavaFile javaFile = (PsiJavaFile) file; final PsiImportList importList = javaFile.getImportList(); if (importList == null) { return false; } final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements(); for (PsiImportStaticStatement importStaticStatement : importStaticStatements) { if (!importStaticStatement.isOnDemand()) { continue; } final PsiClass targetClass = importStaticStatement.resolveTargetClass(); if (targetClass == null) { continue; } final String name = targetClass.getQualifiedName(); if (fqName.equals(name)) { continue; } final PsiField field = targetClass.findFieldByName(memberName, true); if (field != null && (!strict || memberReferenced(field, javaFile))) { return true; } final PsiMethod[] methods = targetClass.findMethodsByName(memberName, true); if (methods.length > 0 && (!strict || membersReferenced(methods, javaFile))) { return true; } } return false; }
private static void addNamesToImport( @NotNull Set<String> names, @NotNull PsiElement scope, @NotNull String thisPackageName, @NotNull Set<String> namesToImportStaticly, PsiFile context) { if (scope instanceof PsiImportList) return; final LinkedList<PsiElement> stack = new LinkedList<PsiElement>(); stack.add(scope); while (!stack.isEmpty()) { final PsiElement child = stack.removeFirst(); if (child instanceof PsiImportList) continue; stack.addAll(Arrays.asList(child.getChildren())); for (final PsiReference reference : child.getReferences()) { if (!(reference instanceof PsiJavaReference)) continue; final PsiJavaReference javaReference = (PsiJavaReference) reference; if (javaReference instanceof JavaClassReference) { if (((JavaClassReference) javaReference).getContextReference() != null) continue; } PsiJavaCodeReferenceElement referenceElement = null; if (reference instanceof PsiJavaCodeReferenceElement) { referenceElement = (PsiJavaCodeReferenceElement) child; if (referenceElement.getQualifier() != null) { continue; } if (reference instanceof PsiJavaCodeReferenceElementImpl && ((PsiJavaCodeReferenceElementImpl) reference).getKind() == PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND) { continue; } } final JavaResolveResult resolveResult = javaReference.advancedResolve(true); PsiElement refElement = resolveResult.getElement(); if (refElement == null && referenceElement != null) { refElement = ResolveClassUtil.resolveClass(referenceElement); // might be uncomplete code } PsiElement currentFileResolveScope = resolveResult.getCurrentFileResolveScope(); if (!(currentFileResolveScope instanceof PsiImportStatementBase)) continue; if (context != null && currentFileResolveScope instanceof JspxImportStatement && context != ((JspxImportStatement) currentFileResolveScope).getDeclarationFile()) { continue; } if (refElement != null) { // Add names imported statically if (referenceElement != null) { if (currentFileResolveScope instanceof PsiImportStaticStatement) { PsiImportStaticStatement importStaticStatement = (PsiImportStaticStatement) currentFileResolveScope; String name = importStaticStatement.getImportReference().getCanonicalText(); if (importStaticStatement.isOnDemand()) { String refName = referenceElement.getReferenceName(); if (refName != null) name = name + "." + refName; } names.add(name); namesToImportStaticly.add(name); continue; } } if (refElement instanceof PsiClass) { String qName = ((PsiClass) refElement).getQualifiedName(); if (hasPackage(qName, thisPackageName)) continue; names.add(qName); } } } } }
public static void invoke( final Project project, PsiFile file, final Editor editor, PsiElement element) { if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; final PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement) element.getParent(); final PsiClass aClass = (PsiClass) refExpr.resolve(); if (aClass == null) { return; } final PsiClass containingClass = PsiUtil.getTopLevelClass(refExpr); if (aClass != containingClass) { PsiImportList importList = ((PsiJavaFile) file).getImportList(); if (importList == null) { return; } boolean alreadyImported = false; for (PsiImportStaticStatement statement : importList.getImportStaticStatements()) { if (!statement.isOnDemand()) continue; PsiClass staticResolve = statement.resolveTargetClass(); if (aClass == staticResolve) { alreadyImported = true; break; } } if (!alreadyImported) { PsiImportStaticStatement importStaticStatement = JavaPsiFacade.getInstance(file.getProject()) .getElementFactory() .createImportStaticStatement(aClass, "*"); importList.add(importStaticStatement); } } List<PsiFile> roots = file.getViewProvider().getAllFiles(); for (final PsiFile root : roots) { PsiElement copy = root.copy(); final PsiManager manager = root.getManager(); final TIntArrayList expressionToDequalifyOffsets = new TIntArrayList(); copy.accept( new JavaRecursiveElementWalkingVisitor() { int delta; @Override public void visitReferenceElement(PsiJavaCodeReferenceElement expression) { if (isParameterizedReference(expression)) return; PsiElement qualifierExpression = expression.getQualifier(); if (qualifierExpression instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement) qualifierExpression).isReferenceTo(aClass)) { try { PsiElement resolved = expression.resolve(); int end = expression.getTextRange().getEndOffset(); qualifierExpression.delete(); delta += end - expression.getTextRange().getEndOffset(); PsiElement after = expression.resolve(); if (manager.areElementsEquivalent(after, resolved)) { expressionToDequalifyOffsets.add( expression.getTextRange().getStartOffset() + delta); } } catch (IncorrectOperationException e) { LOG.error(e); } } super.visitElement(expression); } }); expressionToDequalifyOffsets.forEachDescending( new TIntProcedure() { @Override public boolean execute(int offset) { PsiJavaCodeReferenceElement expression = PsiTreeUtil.findElementOfClassAtOffset( root, offset, PsiJavaCodeReferenceElement.class, false); if (expression == null) { return false; } PsiElement qualifierExpression = expression.getQualifier(); if (qualifierExpression instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement) qualifierExpression).isReferenceTo(aClass)) { qualifierExpression.delete(); if (editor != null) { HighlightManager.getInstance(project) .addRangeHighlight( editor, expression.getTextRange().getStartOffset(), expression.getTextRange().getEndOffset(), EditorColorsManager.getInstance() .getGlobalScheme() .getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES), false, null); } } return true; } }); } }