Lines 24-29
Link Here
|
24 |
import org.eclipse.jdt.core.JavaCore; |
24 |
import org.eclipse.jdt.core.JavaCore; |
25 |
import org.eclipse.jdt.core.JavaModelException; |
25 |
import org.eclipse.jdt.core.JavaModelException; |
26 |
import org.eclipse.jdt.core.Signature; |
26 |
import org.eclipse.jdt.core.Signature; |
|
|
27 |
import org.eclipse.jdt.core.compiler.CharOperation; |
27 |
import org.eclipse.jdt.core.dom.ASTNode; |
28 |
import org.eclipse.jdt.core.dom.ASTNode; |
28 |
import org.eclipse.jdt.core.dom.CompilationUnit; |
29 |
import org.eclipse.jdt.core.dom.CompilationUnit; |
29 |
import org.eclipse.jdt.core.dom.ImportDeclaration; |
30 |
import org.eclipse.jdt.core.dom.ImportDeclaration; |
Lines 33-38
Link Here
|
33 |
import org.eclipse.jdt.core.search.IJavaSearchScope; |
34 |
import org.eclipse.jdt.core.search.IJavaSearchScope; |
34 |
import org.eclipse.jdt.core.search.SearchEngine; |
35 |
import org.eclipse.jdt.core.search.SearchEngine; |
35 |
import org.eclipse.jdt.core.search.TypeNameRequestor; |
36 |
import org.eclipse.jdt.core.search.TypeNameRequestor; |
|
|
37 |
import org.eclipse.jdt.internal.core.JavaProject; |
36 |
import org.eclipse.jface.text.IRegion; |
38 |
import org.eclipse.jface.text.IRegion; |
37 |
import org.eclipse.jface.text.Region; |
39 |
import org.eclipse.jface.text.Region; |
38 |
import org.eclipse.text.edits.DeleteEdit; |
40 |
import org.eclipse.text.edits.DeleteEdit; |
Lines 53-58
Link Here
|
53 |
private final int staticImportOnDemandThreshold; |
55 |
private final int staticImportOnDemandThreshold; |
54 |
|
56 |
|
55 |
private boolean filterImplicitImports; |
57 |
private boolean filterImplicitImports; |
|
|
58 |
private boolean useContextToFilterImplicitImports; |
56 |
private boolean findAmbiguousImports; |
59 |
private boolean findAmbiguousImports; |
57 |
|
60 |
|
58 |
private int flags= 0; |
61 |
private int flags= 0; |
Lines 68-73
Link Here
|
68 |
this.staticImportOnDemandThreshold= staticThreshold; |
71 |
this.staticImportOnDemandThreshold= staticThreshold; |
69 |
|
72 |
|
70 |
this.filterImplicitImports= true; |
73 |
this.filterImplicitImports= true; |
|
|
74 |
this.useContextToFilterImplicitImports= false; |
71 |
this.findAmbiguousImports= true; //!restoreExistingImports; |
75 |
this.findAmbiguousImports= true; //!restoreExistingImports; |
72 |
|
76 |
|
73 |
this.packageEntries= new ArrayList(20); |
77 |
this.packageEntries= new ArrayList(20); |
Lines 168-176
Link Here
|
168 |
} |
172 |
} |
169 |
} |
173 |
} |
170 |
|
174 |
|
171 |
private static String getQualifier(ImportDeclaration decl) { |
175 |
private String getQualifier(ImportDeclaration decl) { |
172 |
String name= decl.getName().getFullyQualifiedName(); |
176 |
String name = decl.getName().getFullyQualifiedName(); |
173 |
return decl.isOnDemand() ? name : Signature.getQualifier(name); |
177 |
/* |
|
|
178 |
* If it's on demand import, return the fully qualified name. (e.g. pack1.Foo.* => pack.Foo, pack1.* => pack1) |
179 |
* This is because we need to have pack1.Foo.* and pack1.Bar under different qualifier groups. |
180 |
*/ |
181 |
if (decl.isOnDemand()) { |
182 |
return name; |
183 |
} |
184 |
return getQualifier(name, decl.isStatic()); |
185 |
} |
186 |
|
187 |
private String getQualifier(String name, boolean isStatic) { |
188 |
// For static imports, return the Type name as well as part of the qualifier |
189 |
if (isStatic || !this.useContextToFilterImplicitImports) { |
190 |
return Signature.getQualifier(name); |
191 |
} |
192 |
|
193 |
char[] searchedName = name.toCharArray(); |
194 |
int index = name.length(); |
195 |
/* Stop at the last fragment */ |
196 |
JavaProject project = (JavaProject) this.compilationUnit.getJavaProject(); |
197 |
do { |
198 |
String testedName = new String(searchedName, 0, index); |
199 |
IJavaElement fragment = null; |
200 |
try { |
201 |
fragment = project.findPackageFragment(testedName); |
202 |
} catch (JavaModelException e) { |
203 |
return name; |
204 |
} |
205 |
if (fragment != null) { |
206 |
return testedName; |
207 |
} |
208 |
try { |
209 |
fragment = project.findType(testedName); |
210 |
} catch (JavaModelException e) { |
211 |
return name; |
212 |
} |
213 |
if (fragment != null) { |
214 |
index = CharOperation.lastIndexOf(Signature.C_DOT, searchedName, 0, index - 1); |
215 |
} else { |
216 |
// we use the heuristic that a name starting with a lowercase is a package name |
217 |
index = CharOperation.lastIndexOf(Signature.C_DOT, searchedName, 0, index - 1); |
218 |
if (Character.isLowerCase(searchedName[index + 1])) { |
219 |
return testedName; |
220 |
} |
221 |
} |
222 |
} while (index >= 0); |
223 |
return name; |
174 |
} |
224 |
} |
175 |
|
225 |
|
176 |
private static String getFullName(ImportDeclaration decl) { |
226 |
private static String getFullName(ImportDeclaration decl) { |
Lines 238-255
Link Here
|
238 |
} |
288 |
} |
239 |
|
289 |
|
240 |
/** |
290 |
/** |
241 |
* Sets that implicit imports (types in default package, CU- package and |
291 |
* Specifies that implicit imports (for types in <code>java.lang</code>, types in the same package as the rewrite |
242 |
* 'java.lang') should not be created. Note that this is a heuristic filter and can |
292 |
* compilation unit and types in the compilation unit's main type) should not be created, except if necessary to |
243 |
* lead to missing imports, e.g. in cases where a type is forced to be specified |
293 |
* resolve an on-demand import conflict. |
244 |
* due to a name conflict. |
294 |
* <p> |
245 |
* By default, the filter is enabled. |
295 |
* The filter is enabled by default. |
246 |
* @param filterImplicitImports The filterImplicitImports to set |
296 |
* </p> |
|
|
297 |
* <p> |
298 |
* Note: {@link #setUseContextToFilterImplicitImports(boolean)} can be used to filter implicit imports |
299 |
* when a context is used. |
300 |
* </p> |
301 |
* |
302 |
* @param filterImplicitImports |
303 |
* if <code>true</code>, implicit imports will be filtered |
304 |
* |
305 |
* @see #setUseContextToFilterImplicitImports(boolean) |
247 |
*/ |
306 |
*/ |
248 |
public void setFilterImplicitImports(boolean filterImplicitImports) { |
307 |
public void setFilterImplicitImports(boolean filterImplicitImports) { |
249 |
this.filterImplicitImports= filterImplicitImports; |
308 |
this.filterImplicitImports= filterImplicitImports; |
250 |
} |
309 |
} |
251 |
|
310 |
|
252 |
/** |
311 |
/** |
|
|
312 |
* Sets whether a context should be used to properly filter implicit imports. |
313 |
* <p> |
314 |
* By default, the option is disabled. |
315 |
* </p> |
316 |
* |
317 |
* @param useContextToFilterImplicitImports the given setting |
318 |
* |
319 |
* @see #setFilterImplicitImports(boolean) |
320 |
* @since 3.6 |
321 |
*/ |
322 |
public void setUseContextToFilterImplicitImports(boolean useContextToFilterImplicitImports) { |
323 |
this.useContextToFilterImplicitImports = useContextToFilterImplicitImports; |
324 |
} |
325 |
|
326 |
/** |
253 |
* When set searches for imports that can not be folded into on-demand |
327 |
* When set searches for imports that can not be folded into on-demand |
254 |
* imports but must be specified explicitly |
328 |
* imports but must be specified explicitly |
255 |
* @param findAmbiguousImports The new value |
329 |
* @param findAmbiguousImports The new value |
Lines 385-394
Link Here
|
385 |
return bestMatch; |
459 |
return bestMatch; |
386 |
} |
460 |
} |
387 |
|
461 |
|
388 |
private static boolean isImplicitImport(String qualifier, ICompilationUnit cu) { |
462 |
private boolean isImplicitImport(String qualifier) { |
389 |
if (JAVA_LANG.equals(qualifier)) { |
463 |
if (JAVA_LANG.equals(qualifier)) { |
390 |
return true; |
464 |
return true; |
391 |
} |
465 |
} |
|
|
466 |
ICompilationUnit cu= this.compilationUnit; |
392 |
String packageName= cu.getParent().getElementName(); |
467 |
String packageName= cu.getParent().getElementName(); |
393 |
if (qualifier.equals(packageName)) { |
468 |
if (qualifier.equals(packageName)) { |
394 |
return true; |
469 |
return true; |
Lines 401-413
Link Here
|
401 |
} |
476 |
} |
402 |
|
477 |
|
403 |
public void addImport(String fullTypeName, boolean isStatic) { |
478 |
public void addImport(String fullTypeName, boolean isStatic) { |
404 |
String typeContainerName= Signature.getQualifier(fullTypeName); |
479 |
String typeContainerName= getQualifier(fullTypeName, isStatic); |
405 |
ImportDeclEntry decl= new ImportDeclEntry(fullTypeName, isStatic, null); |
480 |
ImportDeclEntry decl= new ImportDeclEntry(fullTypeName, isStatic, null); |
406 |
sortIn(typeContainerName, decl, isStatic); |
481 |
sortIn(typeContainerName, decl, isStatic); |
407 |
} |
482 |
} |
408 |
|
483 |
|
409 |
public boolean removeImport(String qualifiedName, boolean isStatic) { |
484 |
public boolean removeImport(String qualifiedName, boolean isStatic) { |
410 |
String containerName= Signature.getQualifier(qualifiedName); |
485 |
String containerName= getQualifier(qualifiedName, isStatic); |
411 |
|
486 |
|
412 |
int nPackages= this.packageEntries.size(); |
487 |
int nPackages= this.packageEntries.size(); |
413 |
for (int i= 0; i < nPackages; i++) { |
488 |
for (int i= 0; i < nPackages; i++) { |
Lines 453-461
Link Here
|
453 |
PackageEntry packEntry= new PackageEntry(typeContainerName, group, isStatic); |
528 |
PackageEntry packEntry= new PackageEntry(typeContainerName, group, isStatic); |
454 |
packEntry.add(decl); |
529 |
packEntry.add(decl); |
455 |
int index= this.packageEntries.indexOf(bestMatch); |
530 |
int index= this.packageEntries.indexOf(bestMatch); |
456 |
if (cmp < 0) { // insert ahead of best match |
531 |
if (cmp < 0) { |
|
|
532 |
// insert ahead of best match |
457 |
this.packageEntries.add(index, packEntry); |
533 |
this.packageEntries.add(index, packEntry); |
458 |
} else { // insert after best match |
534 |
} else { |
|
|
535 |
// insert after best match |
459 |
this.packageEntries.add(index + 1, packEntry); |
536 |
this.packageEntries.add(index + 1, packEntry); |
460 |
} |
537 |
} |
461 |
} |
538 |
} |
Lines 522-538
Link Here
|
522 |
int nPackageEntries= this.packageEntries.size(); |
599 |
int nPackageEntries= this.packageEntries.size(); |
523 |
for (int i= 0; i < nPackageEntries; i++) { |
600 |
for (int i= 0; i < nPackageEntries; i++) { |
524 |
PackageEntry pack= (PackageEntry) this.packageEntries.get(i); |
601 |
PackageEntry pack= (PackageEntry) this.packageEntries.get(i); |
525 |
int nImports= pack.getNumberOfImports(); |
602 |
if (this.filterImplicitImports && !pack.isStatic() && isImplicitImport(pack.getName())) { |
526 |
|
603 |
pack.filterImplicitImports(this.useContextToFilterImplicitImports); |
527 |
if (this.filterImplicitImports && !pack.isStatic() && isImplicitImport(pack.getName(), this.compilationUnit)) { |
|
|
528 |
pack.removeAllNew(onDemandConflicts); |
529 |
nImports= pack.getNumberOfImports(); |
530 |
} |
604 |
} |
|
|
605 |
int nImports= pack.getNumberOfImports(); |
531 |
if (nImports == 0) { |
606 |
if (nImports == 0) { |
532 |
continue; |
607 |
continue; |
533 |
} |
608 |
} |
534 |
|
609 |
|
535 |
|
|
|
536 |
if (spacesBetweenGroups > 0) { |
610 |
if (spacesBetweenGroups > 0) { |
537 |
// add a space between two different groups by looking at the two adjacent imports |
611 |
// add a space between two different groups by looking at the two adjacent imports |
538 |
if (lastPackage != null && !pack.isComment() && !pack.isSameGroup(lastPackage)) { |
612 |
if (lastPackage != null && !pack.isComment() && !pack.isSameGroup(lastPackage)) { |
Lines 928-939
Link Here
|
928 |
return false; |
1002 |
return false; |
929 |
} |
1003 |
} |
930 |
|
1004 |
|
931 |
public void removeAllNew(Set onDemandConflicts) { |
1005 |
public void filterImplicitImports(boolean useContextToFilterImplicitImports) { |
932 |
int nInports= this.importEntries.size(); |
1006 |
int nInports= this.importEntries.size(); |
933 |
for (int i= nInports - 1; i >= 0; i--) { |
1007 |
for (int i= nInports - 1; i >= 0; i--) { |
934 |
ImportDeclEntry curr= getImportAt(i); |
1008 |
ImportDeclEntry curr= getImportAt(i); |
935 |
if (curr.isNew() /*&& (onDemandConflicts == null || onDemandConflicts.contains(curr.getSimpleName()))*/) { |
1009 |
if (curr.isNew()) { |
936 |
this.importEntries.remove(i); |
1010 |
if (!useContextToFilterImplicitImports) { |
|
|
1011 |
this.importEntries.remove(i); |
1012 |
} else { |
1013 |
String elementName = curr.getElementName(); |
1014 |
int lastIndexOf = elementName.lastIndexOf('.'); |
1015 |
boolean internalClassImport = lastIndexOf > getName().length(); |
1016 |
if (!internalClassImport) { |
1017 |
this.importEntries.remove(i); |
1018 |
} |
1019 |
} |
937 |
} |
1020 |
} |
938 |
} |
1021 |
} |
939 |
} |
1022 |
} |