View | Details | Raw Unified | Return to bug 235253 | Differences between
and this patch

Collapse All | Expand All

(-)dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java (-4 / +57 lines)
Lines 24-29 Link Here
24
import org.eclipse.jdt.core.ICompilationUnit;
24
import org.eclipse.jdt.core.ICompilationUnit;
25
import org.eclipse.jdt.core.IImportDeclaration;
25
import org.eclipse.jdt.core.IImportDeclaration;
26
import org.eclipse.jdt.core.ITypeRoot;
26
import org.eclipse.jdt.core.ITypeRoot;
27
import org.eclipse.jdt.core.JavaCore;
27
import org.eclipse.jdt.core.JavaModelException;
28
import org.eclipse.jdt.core.JavaModelException;
28
import org.eclipse.jdt.core.Signature;
29
import org.eclipse.jdt.core.Signature;
29
import org.eclipse.jdt.core.compiler.CharOperation;
30
import org.eclipse.jdt.core.compiler.CharOperation;
Lines 137-142 Link Here
137
	private String[] createdStaticImports;
138
	private String[] createdStaticImports;
138
139
139
	private boolean filterImplicitImports;
140
	private boolean filterImplicitImports;
141
	private boolean useContextToFilterImplicitImports;
140
142
141
	/**
143
	/**
142
	 * Creates a {@link ImportRewrite} from a {@link ICompilationUnit}. If <code>restoreExistingImports</code>
144
	 * Creates a {@link ImportRewrite} from a {@link ICompilationUnit}. If <code>restoreExistingImports</code>
Lines 221-226 Link Here
221
			this.restoreExistingImports= false;
223
			this.restoreExistingImports= false;
222
		}
224
		}
223
		this.filterImplicitImports= true;
225
		this.filterImplicitImports= true;
226
		// consider that no contexts are used
227
		this.useContextToFilterImplicitImports = false;
224
228
225
		this.defaultContext= new ImportRewriteContext() {
229
		this.defaultContext= new ImportRewriteContext() {
226
			public int findInContext(String qualifier, String name, int kind) {
230
			public int findInContext(String qualifier, String name, int kind) {
Lines 303-317 Link Here
303
	}
307
	}
304
308
305
	/**
309
	/**
306
	 * Specifies that implicit imports (types in default package, package <code>java.lang</code> or
310
	 * Specifies that implicit imports (for types in <code>java.lang</code>, types in the same package as the rewrite
307
	 * in the same package as the rewrite compilation unit should not be created except if necessary
311
	 * compilation unit, and types in the compilation unit's main type) should not be created, except if necessary to
308
	 * to resolve an on-demand import conflict. The filter is enabled by default.
312
	 * resolve an on-demand import conflict.
309
	 * @param filterImplicitImports if set, implicit imports will be filtered.
313
	 * <p>
314
	 * The filter is enabled by default.
315
	 * </p>
316
	 * <p>
317
	 * Note: {@link #setUseContextToFilterImplicitImports(boolean)} can be used to filter implicit imports
318
	 * when a context is used.
319
	 * </p>
320
	 * 
321
	 * @param filterImplicitImports
322
	 *            if <code>true</code>, implicit imports will be filtered
323
	 * 
324
	 * @see #setUseContextToFilterImplicitImports(boolean)
310
	 */
325
	 */
311
	public void setFilterImplicitImports(boolean filterImplicitImports) {
326
	public void setFilterImplicitImports(boolean filterImplicitImports) {
312
		this.filterImplicitImports= filterImplicitImports;
327
		this.filterImplicitImports= filterImplicitImports;
313
	}
328
	}
314
329
330
	/**
331
	 * Sets whether a context should be used to properly filter implicit imports.
332
	 * <p>
333
	 * By default, the option is disabled to preserve existing behavior.
334
	 * </p>
335
	 * 
336
	 * @param useContextToFilterImplicitImports the given setting
337
	 * 
338
	 * @see #setFilterImplicitImports(boolean)
339
	 * @since 3.6
340
	 */
341
	public void setUseContextToFilterImplicitImports(boolean useContextToFilterImplicitImports) {
342
		this.useContextToFilterImplicitImports = useContextToFilterImplicitImports;
343
	}
344
	
315
	private static int compareImport(char prefix, String qualifier, String name, String curr) {
345
	private static int compareImport(char prefix, String qualifier, String name, String curr) {
316
		if (curr.charAt(0) != prefix || !curr.endsWith(name)) {
346
		if (curr.charAt(0) != prefix || !curr.endsWith(name)) {
317
			return ImportRewriteContext.RES_NAME_UNKNOWN;
347
			return ImportRewriteContext.RES_NAME_UNKNOWN;
Lines 360-368 Link Here
360
				}
390
				}
361
			}
391
			}
362
		}
392
		}
393
		if (this.filterImplicitImports && this.useContextToFilterImplicitImports) {
394
			String fPackageName= this.compilationUnit.getParent().getElementName();
395
			String mainTypeSimpleName= JavaCore.removeJavaLikeExtension(this.compilationUnit.getElementName());
396
			String fMainTypeName= concatenateName(fPackageName, mainTypeSimpleName);
397
			if (kind == ImportRewriteContext.KIND_TYPE
398
					&& (qualifier.equals(fPackageName)
399
							|| fMainTypeName.equals(concatenateName(qualifier, name))))
400
				return ImportRewriteContext.RES_NAME_FOUND;
401
		}
363
		return ImportRewriteContext.RES_NAME_UNKNOWN;
402
		return ImportRewriteContext.RES_NAME_UNKNOWN;
364
	}
403
	}
365
404
405
	private static String concatenateName(String name1, String name2) {
406
		StringBuffer buf= new StringBuffer();
407
		if (name1 != null && name1.length() > 0) {
408
			buf.append(name1);
409
		}
410
		if (name2 != null && name2.length() > 0) {
411
			if (buf.length() > 0) {
412
				buf.append('.');
413
			}
414
			buf.append(name2);
415
		}
416
		return buf.toString();
417
	}
366
	/**
418
	/**
367
	 * Adds a new import to the rewriter's record and returns a {@link Type} node that can be used
419
	 * Adds a new import to the rewriter's record and returns a {@link Type} node that can be used
368
	 * in the code as a reference to the type. The type binding can be an array binding, type variable or wildcard.
420
	 * in the code as a reference to the type. The type binding can be an array binding, type variable or wildcard.
Lines 995-1000 Link Here
995
1047
996
			ImportRewriteAnalyzer computer= new ImportRewriteAnalyzer(this.compilationUnit, usedAstRoot, this.importOrder, this.importOnDemandThreshold, this.staticImportOnDemandThreshold, this.restoreExistingImports);
1048
			ImportRewriteAnalyzer computer= new ImportRewriteAnalyzer(this.compilationUnit, usedAstRoot, this.importOrder, this.importOnDemandThreshold, this.staticImportOnDemandThreshold, this.restoreExistingImports);
997
			computer.setFilterImplicitImports(this.filterImplicitImports);
1049
			computer.setFilterImplicitImports(this.filterImplicitImports);
1050
			computer.setUseContextToFilterImplicitImports(this.useContextToFilterImplicitImports);
998
1051
999
			if (this.addedImports != null) {
1052
			if (this.addedImports != null) {
1000
				for (int i= 0; i < this.addedImports.size(); i++) {
1053
				for (int i= 0; i < this.addedImports.size(); i++) {
(-)dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java (-23 / +106 lines)
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
		}
(-)src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewriteTest.java (+139 lines)
Lines 572-577 Link Here
572
		assertEqualString(cu.getSource(), buf.toString());
572
		assertEqualString(cu.getSource(), buf.toString());
573
	}
573
	}
574
574
575
	/**
576
	 * Test that the Inner class import comes in the right order (i.e. after the enclosing type's import) when re-organized
577
	 * 
578
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=194358"
579
	 */
580
	public void testBug194358() throws Exception {
581
582
		StringBuffer buf= new StringBuffer();
583
		buf.append("package pack1;\n");
584
		buf.append("\n");
585
		buf.append("import pack2.A;\n");
586
		buf.append("import pack2.A.Inner;\n");
587
		buf.append("import pack2.B;\n");
588
		buf.append("\n");
589
		buf.append("public class C {\n");
590
		buf.append("}\n");
591
592
		IPackageFragment pack1= this.sourceFolder.createPackageFragment("pack1", false, null);
593
		ICompilationUnit cu= pack1.createCompilationUnit("C.java", buf.toString(), false, null);
594
595
		// We need to actually make some state in the AST for the classes, to test that we can 
596
		// disambiguate between packages and inner classes (see the bug for details).
597
		IPackageFragment pack2= this.sourceFolder.createPackageFragment("pack2", false, null);
598
		ICompilationUnit aUnit= pack2.createCompilationUnit("A.java", "", false, null);
599
		ICompilationUnit bUnit= pack2.createCompilationUnit("B.java", "", false, null);
600
		bUnit.createType("class B {}", null, false, null);
601
602
		IType aType= aUnit.createType("class A {}", null, false, null);
603
		aType.createType("class Inner {}", null, false, null);
604
		String[] order= new String[] { "java" };
605
606
		ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, false);
607
		imports.setUseContextToFilterImplicitImports(true);
608
		imports.addImport("pack2.A");
609
		imports.addImport("pack2.B");
610
		imports.addImport("pack2.A.Inner");
611
612
		apply(imports);
613
614
		buf= new StringBuffer();
615
		buf.append("package pack1;\n");
616
		buf.append("\n");
617
		buf.append("import pack2.A;\n");
618
		buf.append("import pack2.A.Inner;\n");
619
		buf.append("import pack2.B;\n");
620
		buf.append("\n");
621
		buf.append("public class C {\n");
622
		buf.append("}\n");
623
		assertEqualString(cu.getSource(), buf.toString());
624
	}
625
626
	/**
627
	 * Test that a valid inner class import is not removed even when the container
628
	 * class is implicitly available. This tests the case where the classes are in 
629
	 * different compilation units.
630
	 * 
631
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=194358"
632
	 */
633
	public void testBug194358a() throws Exception {
634
		StringBuffer buf= new StringBuffer();
635
		buf.append("package com.pack1;\n");
636
		buf.append("\n");
637
		buf.append("import com.pack1.A;\n");
638
		buf.append("import com.pack1.A.Inner;\n");
639
		buf.append("import com.pack2.B;\n");
640
		buf.append("\n");
641
		buf.append("public class C {\n");
642
		buf.append("}\n");
643
644
		IPackageFragment pack1= this.sourceFolder.createPackageFragment("com.pack1", false, null);
645
		ICompilationUnit cu= pack1.createCompilationUnit("C.java", buf.toString(), false, null);
646
		ICompilationUnit aUnit= pack1.createCompilationUnit("A.java", "", false, null);
647
648
		IPackageFragment pack2= this.sourceFolder.createPackageFragment("com.pack2", false, null);
649
		ICompilationUnit bUnit= pack2.createCompilationUnit("B.java", "", false, null);
650
		bUnit.createType("class B {}", null, false, null);
651
		IType aType= aUnit.createType("class A {}", null, false, null);
652
		aType.createType("class Inner {}", null, false, null);
653
		String[] order= new String[] { "java" };
654
655
		ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, false);
656
		imports.setUseContextToFilterImplicitImports(false);
657
		imports.addImport("com.pack1.A");
658
		imports.addImport("com.pack1.A.Inner");
659
		imports.addImport("com.pack2.B");
660
661
		apply(imports);
662
663
		buf= new StringBuffer();
664
		buf.append("package com.pack1;\n");
665
		buf.append("\n");
666
		buf.append("import com.pack1.A.Inner;\n");
667
		buf.append("import com.pack2.B;\n");
668
		buf.append("\n");
669
		buf.append("public class C {\n");
670
		buf.append("}\n");
671
		assertEqualString(cu.getSource(), buf.toString());
672
	}
673
	/**
674
	 * Test that the Inner type imports are not removed while organizing even though the 
675
	 * containing class is implicitly available - for the case when both the classes are 
676
	 * in the same compilation unit
677
	 * 
678
	 * see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=235253"
679
	 */
680
	public void testBug235253() throws Exception {
681
		StringBuffer buf= new StringBuffer();
682
		buf.append("package bug;\n");
683
		buf.append("\n");
684
		buf.append("class Bug {\n");
685
		buf.append("public void addFile(File file) {}\n");
686
		buf.append("\tinterface Proto{};\n");
687
		buf.append("}\n");		
688
		buf.append("class Foo implements Proto{}");
689
690
		IPackageFragment pack1= this.sourceFolder.createPackageFragment("bug", false, null);
691
		ICompilationUnit cu= pack1.createCompilationUnit("Bug.java", buf.toString(), false, null);
692
		String[] order= new String[] { "bug" , "java" };
693
		ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, false);
694
		imports.setUseContextToFilterImplicitImports(true);
695
		imports.addImport("bug.Bug.Proto");
696
		imports.addImport("java.io.File"); 
697
		
698
		apply(imports);
699
		buf = new StringBuffer();
700
		buf.append("package bug;\n");
701
		buf.append("\n");
702
		buf.append("import bug.Bug.Proto;\n");
703
		buf.append("\n");
704
		buf.append("import java.io.File;\n");
705
		buf.append("\n");
706
		buf.append("class Bug {\n");
707
		buf.append("public void addFile(File file) {}\n");
708
		buf.append("\tinterface Proto{};\n");
709
		buf.append("}\n");		
710
		buf.append("class Foo implements Proto{}");
711
		assertEqualString(cu.getSource(), buf.toString());
712
	}
713
		
575
	public void testAddStaticImports1() throws Exception {
714
	public void testAddStaticImports1() throws Exception {
576
715
577
		IPackageFragment pack1= this.sourceFolder.createPackageFragment("pack1", false, null);
716
		IPackageFragment pack1= this.sourceFolder.createPackageFragment("pack1", false, null);

Return to bug 235253