IDEADEV-40411

This commit is contained in:
Alexey Kudravtsev
2009-09-16 18:29:54 +04:00
parent 1e7e771af0
commit b6f59a2620
6 changed files with 81 additions and 78 deletions

View File

@@ -4,6 +4,7 @@ import com.intellij.lang.ASTNode;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -27,6 +28,7 @@ import gnu.trove.THashSet;
import gnu.trove.TObjectIntHashMap;
import gnu.trove.TObjectIntProcedure;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -36,11 +38,11 @@ public class ImportHelper{
private final CodeStyleSettings mySettings;
@NonNls private static final String JAVA_LANG_PACKAGE = "java.lang";
public ImportHelper(CodeStyleSettings settings){
public ImportHelper(@NotNull CodeStyleSettings settings){
mySettings = settings;
}
public PsiImportList prepareOptimizeImportsResult(final PsiJavaFile file) {
public PsiImportList prepareOptimizeImportsResult(@NotNull final PsiJavaFile file) {
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(file.getProject());
final Set<String> namesToImportStaticly = new THashSet<String>();
@@ -92,7 +94,7 @@ public class ImportHelper{
class MyVisitorProcedure implements TObjectIntProcedure<String> {
private final boolean myIsVisitingPackages;
public MyVisitorProcedure(boolean isVisitingPackages) {
MyVisitorProcedure(boolean isVisitingPackages) {
myIsVisitingPackages = isVisitingPackages;
}
@@ -126,9 +128,11 @@ public class ImportHelper{
}
}
private static Set<String> findSingleImports(final PsiJavaFile file,
String[] names,
final Set<String> onDemandImports, Set<String> namesToImportStaticly) {
@NotNull
private static Set<String> findSingleImports(@NotNull final PsiJavaFile file,
@NotNull String[] names,
@NotNull final Set<String> onDemandImports,
@NotNull Set<String> namesToImportStaticly) {
final GlobalSearchScope resolveScope = file.getResolveScope();
Set<String> namesToUseSingle = new THashSet<String>();
final String thisPackageName = file.getPackageName();
@@ -189,9 +193,11 @@ public class ImportHelper{
return namesToUseSingle;
}
private static String buildImportListText(String[] names,
final Set<String> packagesOrClassesToImportOnDemand,
final Set<String> namesToUseSingle, Set<String> namesToImportStaticly) {
@NotNull
private static String buildImportListText(@NotNull String[] names,
@NotNull final Set<String> packagesOrClassesToImportOnDemand,
@NotNull final Set<String> namesToUseSingle,
@NotNull Set<String> namesToImportStaticly) {
final Set<String> importedPackagesOrClasses = new THashSet<String>();
@NonNls final StringBuilder buffer = new StringBuilder();
for (String name : names) {
@@ -222,7 +228,7 @@ public class ImportHelper{
* Adds import if it is needed.
* @return false when the FQ-name have to be used in code (e.g. when conflicting imports already exist)
*/
public boolean addImport(PsiJavaFile file, PsiClass refClass){
public boolean addImport(@NotNull PsiJavaFile file, @NotNull PsiClass refClass){
final JavaPsiFacade facade = JavaPsiFacade.getInstance(file.getProject());
PsiElementFactory factory = facade.getElementFactory();
PsiResolveHelper helper = facade.getResolveHelper();
@@ -252,16 +258,14 @@ public class ImportHelper{
useOnDemand = false;
}
ArrayList<PsiElement> classesToReimport = new ArrayList<PsiElement>();
List<PsiElement> classesToReimport = new ArrayList<PsiElement>();
PsiJavaCodeReferenceElement[] importRefs = getImportsFromPackage(file, packageName);
List<PsiJavaCodeReferenceElement> importRefs = getImportsFromPackage(file, packageName);
if (useOnDemand){
if (mySettings.USE_SINGLE_CLASS_IMPORTS){
if (importRefs.length + 1 < mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND
&& !mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND.contains(packageName)
){
useOnDemand = false;
}
if (mySettings.USE_SINGLE_CLASS_IMPORTS &&
importRefs.size() + 1 < mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND &&
!mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND.contains(packageName)) {
useOnDemand = false;
}
// name of class we try to import is the same as of the class defined in this file
if (curRefClass != null) {
@@ -334,7 +338,8 @@ public class ImportHelper{
return true;
}
private static PsiJavaCodeReferenceElement[] getImportsFromPackage(PsiJavaFile file, String packageName){
@NotNull
private static List<PsiJavaCodeReferenceElement> getImportsFromPackage(@NotNull PsiJavaFile file, @NotNull String packageName){
PsiClass[] refs = file.getSingleClassImports(true);
List<PsiJavaCodeReferenceElement> array = new ArrayList<PsiJavaCodeReferenceElement>();
for (PsiClass ref1 : refs) {
@@ -346,10 +351,10 @@ public class ImportHelper{
}
}
}
return array.toArray(new PsiJavaCodeReferenceElement[array.size()]);
return array;
}
private static PsiClass findSingleImportByShortName(PsiJavaFile file, String shortClassName){
private static PsiClass findSingleImportByShortName(@NotNull PsiJavaFile file, @NotNull String shortClassName){
PsiClass[] refs = file.getSingleClassImports(true);
for (PsiClass ref : refs) {
String className = ref.getQualifiedName();
@@ -366,7 +371,7 @@ public class ImportHelper{
return null;
}
private static PsiPackage findImportOnDemand(PsiJavaFile file, String packageName){
private static PsiPackage findImportOnDemand(@NotNull PsiJavaFile file, @NotNull String packageName){
PsiElement[] refs = file.getOnDemandImports(false, true);
for (PsiElement ref : refs) {
if (ref instanceof PsiPackage && ((PsiPackage)ref).getQualifiedName().equals(packageName)) {
@@ -376,25 +381,24 @@ public class ImportHelper{
return null;
}
public ASTNode getDefaultAnchor(PsiImportList list, PsiImportStatementBase statement){
public ASTNode getDefaultAnchor(@NotNull PsiImportList list, @NotNull PsiImportStatementBase statement){
PsiJavaCodeReferenceElement ref = statement.getImportReference();
if (ref == null) return null;
int entryIndex = findEntryIndex(statement);
PsiImportStatementBase[] allStatements = list.getAllImportStatements();
int[] entries = ArrayUtil.newIntArray(allStatements.length);
ArrayList<PsiImportStatementBase> array = new ArrayList<PsiImportStatementBase>();
List<PsiImportStatementBase> statements = new ArrayList<PsiImportStatementBase>();
for(int i = 0; i < allStatements.length; i++){
PsiImportStatementBase statement1 = allStatements[i];
int entryIndex1 = findEntryIndex(statement1);
entries[i] = entryIndex1;
if (entryIndex1 == entryIndex){
array.add(statement1);
statements.add(statement1);
}
}
PsiImportStatementBase[] statements = array.toArray(new PsiImportStatementBase[array.size()]);
if (statements.length == 0){
if (statements.isEmpty()){
int index;
for(index = entries.length - 1; index >= 0; index--){
if (entries[index] < entryIndex) break;
@@ -402,47 +406,40 @@ public class ImportHelper{
index++;
return index < entries.length ? SourceTreeToPsiMap.psiElementToTree(allStatements[index]) : null;
}
else{
//TODO : alphabetical sorting
String text = ref.getCanonicalText();
else {
String refText = ref.getCanonicalText();
if (statement.isOnDemand()){
text += ".";
refText += ".";
}
int index = text.length();
while(true){
index = text.lastIndexOf('.', index - 1);
if (index < 0) break;
String prefix = text.substring(0, index + 1);
PsiImportStatementBase last = null;
PsiImportStatementBase lastStrict = null;
for (PsiImportStatementBase statement1 : statements) {
PsiJavaCodeReferenceElement ref1 = statement1.getImportReference();
if (ref1 != null) {
String text1 = ref1.getCanonicalText();
if (statement1.isOnDemand()) {
text1 += ".";
}
if (text1.startsWith(prefix)) {
last = statement1;
if (text1.indexOf('.', prefix.length()) < 0) {
lastStrict = statement1;
}
}
}
PsiImportStatementBase insertBefore = null;
PsiImportStatementBase insertAfter = null;
for (PsiImportStatementBase statement1 : statements) {
PsiJavaCodeReferenceElement ref1 = statement1.getImportReference();
if (ref1 == null) {
continue;
}
String refTextThis = ref1.getCanonicalText();
if (statement1.isOnDemand()) {
refTextThis += ".";
}
if (lastStrict != null){
return SourceTreeToPsiMap.psiElementToTree(lastStrict).getTreeNext();
int comp = Comparing.compare(refText, refTextThis);
if (comp < 0 && insertBefore == null) {
insertBefore = statement1;
}
if (last != null){
return SourceTreeToPsiMap.psiElementToTree(last).getTreeNext();
if (comp > 0) {
insertAfter = statement1;
}
}
if (insertBefore != null) return insertBefore.getNode();
if (insertAfter != null) return insertAfter.getNode().getTreeNext();
return null;
}
}
public int getEmptyLinesBetween(PsiImportStatementBase statement1, PsiImportStatementBase statement2){
public int getEmptyLinesBetween(@NotNull PsiImportStatementBase statement1, @NotNull PsiImportStatementBase statement2){
int index1 = findEntryIndex(statement1);
int index2 = findEntryIndex(statement2);
if (index1 == index2) return 0;
@@ -465,7 +462,7 @@ public class ImportHelper{
return maxSpace;
}
private boolean isToUseImportOnDemand(String packageName, int classCount, boolean isStaticImportNeeded){
private boolean isToUseImportOnDemand(@NotNull String packageName, int classCount, boolean isStaticImportNeeded){
if (!mySettings.USE_SINGLE_CLASS_IMPORTS) return true;
int limitCount = isStaticImportNeeded ? mySettings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND :
mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND;
@@ -475,7 +472,7 @@ public class ImportHelper{
return table != null && table.contains(packageName);
}
private int findEntryIndex(String packageName){
private int findEntryIndex(@NotNull String packageName){
Entry[] entries = mySettings.IMPORT_LAYOUT_TABLE.getEntries();
PackageEntry bestEntry = null;
int bestEntryIndex = -1;
@@ -503,7 +500,7 @@ public class ImportHelper{
return bestEntryIndex;
}
public int findEntryIndex(PsiImportStatementBase statement){
public int findEntryIndex(@NotNull PsiImportStatementBase statement){
PsiJavaCodeReferenceElement ref = statement.getImportReference();
if (ref == null) return -1;
String packageName;
@@ -517,7 +514,8 @@ public class ImportHelper{
return findEntryIndex(packageName);
}
private static String[] collectNamesToImport(PsiJavaFile file, Set<String> namesToImportStaticly){
@NotNull
private static String[] collectNamesToImport(@NotNull PsiJavaFile file, @NotNull Set<String> namesToImportStaticly){
Set<String> names = new THashSet<String>();
final JspFile jspFile = JspPsiUtil.getJspFile(file);
@@ -537,7 +535,9 @@ public class ImportHelper{
return ArrayUtil.toStringArray(names);
}
private static void collectNamesToImport(final Set<String> names, final PsiJavaFile file, final Set<String> namesToImportStaticly,
private static void collectNamesToImport(@NotNull final Set<String> names,
@NotNull final PsiJavaFile file,
@NotNull final Set<String> namesToImportStaticly,
PsiFile context) {
String packageName = file.getPackageName();
@@ -547,10 +547,11 @@ public class ImportHelper{
}
}
private static void addNamesToImport(Set<String> names,
PsiElement scope,
String thisPackageName,
Set<String> namesToImportStaticly, PsiFile context){
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>();
@@ -616,7 +617,9 @@ public class ImportHelper{
}
}
private static void addUnresolvedImportNames(Set<String> set, PsiJavaFile file, Set<String> namesToImportStaticly) {
private static void addUnresolvedImportNames(@NotNull Set<String> set,
@NotNull PsiJavaFile file,
@NotNull Set<String> namesToImportStaticly) {
PsiImportStatementBase[] imports = file.getImportList().getAllImportStatements();
for (PsiImportStatementBase anImport : imports) {
PsiJavaCodeReferenceElement ref = anImport.getImportReference();
@@ -635,7 +638,7 @@ public class ImportHelper{
}
}
public static boolean isImplicitlyImported(String className, PsiJavaFile file) {
public static boolean isImplicitlyImported(@NotNull String className, @NotNull PsiJavaFile file) {
String[] packageNames = file.getImplicitlyImportedPackages();
for (String packageName : packageNames) {
if (hasPackage(className, packageName)) return true;
@@ -643,14 +646,15 @@ public class ImportHelper{
return false;
}
public static boolean hasPackage(String className, String packageName){
public static boolean hasPackage(@NotNull String className, @NotNull String packageName){
if (!className.startsWith(packageName)) return false;
if (className.length() == packageName.length()) return false;
if (packageName.length() > 0 && className.charAt(packageName.length()) != '.') return false;
return className.indexOf('.', packageName.length() + 1) < 0;
}
private static String getPackageOrClassName(String className){
@NotNull
private static String getPackageOrClassName(@NotNull String className){
int dotIndex = className.lastIndexOf('.');
return dotIndex < 0 ? "" : className.substring(0, dotIndex);
}

View File

@@ -5,21 +5,20 @@ import com.intellij.psi.PsiImportList;
import com.intellij.psi.PsiImportStatementBase;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.codeStyle.ImportHelper;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
public class ImportListElement extends CompositeElement{
public ImportListElement() {
super(Constants.IMPORT_LIST);
super(JavaElementType.IMPORT_LIST);
}
public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before){
if (before == null){
if (first == last && (first.getElementType() == ElementType.IMPORT_STATEMENT || first.getElementType() == ElementType.IMPORT_STATIC_STATEMENT)){
if (first == last && (first.getElementType() == JavaElementType.IMPORT_STATEMENT || first.getElementType() == JavaElementType.IMPORT_STATIC_STATEMENT)){
anchor = getDefaultAnchor((PsiImportList)SourceTreeToPsiMap.treeElementToPsi(this),
(PsiImportStatementBase)SourceTreeToPsiMap.treeElementToPsi(first));
before = Boolean.TRUE;

View File

@@ -1,5 +1,5 @@
import java.io.OutputStream;
import java.io.IOException;
import java.io.OutputStream;
class A {
{

View File

@@ -1,5 +1,5 @@
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
class B {
public final A myDelegate = new A();

View File

@@ -1,6 +1,5 @@
import org.junit.Test;
import org.junit.Before;
import org.junit.Test;
public class T {
private int i;

View File

@@ -65,6 +65,7 @@ public abstract class PsiNameHelper {
*/
public abstract boolean isQualifiedName(@Nullable String text);
@NotNull
public static String getShortClassName(@NotNull String referenceText) {
return getShortClassName(referenceText, true);
}