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

Collapse All | Expand All

(-)dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java (-21 / +55 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 168-176 Link Here
168
		}
170
		}
169
	}
171
	}
170
172
171
	private static String getQualifier(ImportDeclaration decl) {
173
	private String getQualifier(ImportDeclaration decl) {
172
		String name= decl.getName().getFullyQualifiedName();
174
		String name = decl.getName().getFullyQualifiedName();
173
		return decl.isOnDemand() ? name : Signature.getQualifier(name);
175
		/*
176
		 * If it's on demand import, return the fully qualified name. (e.g. pack1.Foo.* => pack.Foo, pack1.* => pack1)
177
		 * This is because we need to have pack1.Foo.* and pack1.Bar under different qualifier groups.
178
		 */
179
		if (decl.isOnDemand()) {
180
			return name;
181
		}
182
		return getQualifier(Signature.getQualifier(name), decl.isStatic());
183
	}
184
185
	private String getQualifier(String name, boolean isStatic) {
186
		// For static imports, return the Type name as well as part of the qualifier
187
		if (isStatic) {
188
			return Signature.getQualifier(name);
189
		}
190
191
		char[] searchedName = name.toCharArray();
192
		int index = name.length();
193
		/* Stop at the last fragment */
194
		do {
195
			String potentialPackageName = new String(searchedName, 0, index);
196
			IJavaElement fragment = null;
197
			try {
198
				fragment = ((JavaProject) this.compilationUnit.getJavaProject()).findPackageFragment(potentialPackageName);
199
			} catch (JavaModelException e) {
200
				return name;
201
			}
202
			if (fragment != null) {
203
				return potentialPackageName;
204
			}
205
			index = CharOperation.lastIndexOf(Signature.C_DOT, searchedName, 0, index - 1);
206
		} while (index >= 0); 
207
		return name;
174
	}
208
	}
175
209
176
	private static String getFullName(ImportDeclaration decl) {
210
	private static String getFullName(ImportDeclaration decl) {
Lines 390-413 Link Here
390
			return true;
424
			return true;
391
		}
425
		}
392
		String packageName= cu.getParent().getElementName();
426
		String packageName= cu.getParent().getElementName();
393
		if (qualifier.equals(packageName)) {
427
		return qualifier.equals(packageName);
394
			return true;
395
		}
396
		String mainTypeName= JavaCore.removeJavaLikeExtension(cu.getElementName());
397
		if (packageName.length() == 0) {
398
			return qualifier.equals(mainTypeName);
399
		}
400
		return qualifier.equals(packageName +'.' + mainTypeName);
401
	}
428
	}
402
429
403
	public void addImport(String fullTypeName, boolean isStatic) {
430
	public void addImport(String fullTypeName, boolean isStatic) {
404
		String typeContainerName= Signature.getQualifier(fullTypeName);
431
		String typeContainerName= getQualifier(fullTypeName, isStatic);
405
		ImportDeclEntry decl= new ImportDeclEntry(fullTypeName, isStatic, null);
432
		ImportDeclEntry decl= new ImportDeclEntry(fullTypeName, isStatic, null);
406
		sortIn(typeContainerName, decl, isStatic);
433
		sortIn(typeContainerName, decl, isStatic);
407
	}
434
	}
408
435
409
	public boolean removeImport(String qualifiedName, boolean isStatic) {
436
	public boolean removeImport(String qualifiedName, boolean isStatic) {
410
		String containerName= Signature.getQualifier(qualifiedName);
437
		String containerName= getQualifier(qualifiedName, isStatic);
411
438
412
		int nPackages= this.packageEntries.size();
439
		int nPackages= this.packageEntries.size();
413
		for (int i= 0; i < nPackages; i++) {
440
		for (int i= 0; i < nPackages; i++) {
Lines 453-461 Link Here
453
				PackageEntry packEntry= new PackageEntry(typeContainerName, group, isStatic);
480
				PackageEntry packEntry= new PackageEntry(typeContainerName, group, isStatic);
454
				packEntry.add(decl);
481
				packEntry.add(decl);
455
				int index= this.packageEntries.indexOf(bestMatch);
482
				int index= this.packageEntries.indexOf(bestMatch);
456
				if (cmp < 0) { 	// insert ahead of best match
483
				if (cmp < 0) {
484
					// insert ahead of best match
457
					this.packageEntries.add(index, packEntry);
485
					this.packageEntries.add(index, packEntry);
458
				} else {		// insert after best match
486
				} else {
487
					// insert after best match
459
					this.packageEntries.add(index + 1, packEntry);
488
					this.packageEntries.add(index + 1, packEntry);
460
				}
489
				}
461
			}
490
			}
Lines 522-533 Link Here
522
			int nPackageEntries= this.packageEntries.size();
551
			int nPackageEntries= this.packageEntries.size();
523
			for (int i= 0; i < nPackageEntries; i++) {
552
			for (int i= 0; i < nPackageEntries; i++) {
524
				PackageEntry pack= (PackageEntry) this.packageEntries.get(i);
553
				PackageEntry pack= (PackageEntry) this.packageEntries.get(i);
525
				int nImports= pack.getNumberOfImports();
526
554
527
				if (this.filterImplicitImports && !pack.isStatic() && isImplicitImport(pack.getName(), this.compilationUnit)) {
555
				if (this.filterImplicitImports && !pack.isStatic() && isImplicitImport(pack.getName(), this.compilationUnit)) {
528
					pack.removeAllNew(onDemandConflicts);
556
					pack.filterImplicitImports();
529
					nImports= pack.getNumberOfImports();
530
				}
557
				}
558
				int nImports= pack.getNumberOfImports();
559
531
				if (nImports == 0) {
560
				if (nImports == 0) {
532
					continue;
561
					continue;
533
				}
562
				}
Lines 930-941 Link Here
930
			return false;
959
			return false;
931
		}
960
		}
932
961
933
		public void removeAllNew(Set onDemandConflicts) {
962
		public void filterImplicitImports() {
934
			int nInports= this.importEntries.size();
963
			int nInports= this.importEntries.size();
935
			for (int i= nInports - 1; i >= 0; i--) {
964
			for (int i= nInports - 1; i >= 0; i--) {
936
				ImportDeclEntry curr= getImportAt(i);
965
				ImportDeclEntry curr= getImportAt(i);
937
				if (curr.isNew() /*&& (onDemandConflicts == null || onDemandConflicts.contains(curr.getSimpleName()))*/) {
966
				String elementName = curr.getElementName();
938
					this.importEntries.remove(i);
967
				int lastIndexOf = elementName.lastIndexOf('.');
968
				boolean internalClassImport = lastIndexOf > getName().length();
969
				if (curr.isNew()) {
970
					if (!internalClassImport) {
971
						this.importEntries.remove(i);
972
					}
939
				}
973
				}
940
			}
974
			}
941
		}
975
		}
(-)src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewriteTest.java (-5 / +144 lines)
Lines 61-67 Link Here
61
61
62
	protected void setUp() throws Exception {
62
	protected void setUp() throws Exception {
63
		super.setUp();
63
		super.setUp();
64
64
	
65
		IJavaProject proj= createJavaProject("P", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
65
		IJavaProject proj= createJavaProject("P", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
66
		proj.setOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
66
		proj.setOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
67
		proj.setOption(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
67
		proj.setOption(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
Lines 70-80 Link Here
70
		proj.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
70
		proj.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
71
		proj.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
71
		proj.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
72
		proj.setOption(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, String.valueOf(99));
72
		proj.setOption(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, String.valueOf(99));
73
73
	
74
		proj.setOption(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BETWEEN_IMPORT_GROUPS, String.valueOf(1));
74
		proj.setOption(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BETWEEN_IMPORT_GROUPS, String.valueOf(1));
75
75
	
76
77
		this.sourceFolder = getPackageFragmentRoot("P", "src");
76
		this.sourceFolder = getPackageFragmentRoot("P", "src");
77
		this.sourceFolder.createPackageFragment("java.util", false, null);
78
		this.sourceFolder.createPackageFragment("java.net", false, null);
79
		this.sourceFolder.createPackageFragment("java.awt", false, null);
80
		this.sourceFolder.createPackageFragment("pack", false, null);
78
81
79
		waitUntilIndexesReady();
82
		waitUntilIndexesReady();
80
	}
83
	}
Lines 469-476 Link Here
469
		buf= new StringBuffer();
472
		buf= new StringBuffer();
470
		buf.append("package pack1;\n");
473
		buf.append("package pack1;\n");
471
		buf.append("\n");
474
		buf.append("\n");
472
		buf.append("import p.Inner;\n");
473
		buf.append("import p.A.*;\n");
475
		buf.append("import p.A.*;\n");
476
		buf.append("import p.Inner;\n");
474
		buf.append("\n");
477
		buf.append("\n");
475
		buf.append("public class C {\n");
478
		buf.append("public class C {\n");
476
		buf.append("}\n");
479
		buf.append("}\n");
Lines 572-577 Link Here
572
		assertEqualString(cu.getSource(), buf.toString());
575
		assertEqualString(cu.getSource(), buf.toString());
573
	}
576
	}
574
577
578
	/**
579
	 * Test that the Inner class import comes in the right order (i.e. after the enclosing type's import) when re-organized
580
	 * 
581
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=194358"
582
	 */
583
	public void testBug194358() throws Exception {
584
585
	  StringBuffer buf= new StringBuffer();
586
	  buf.append("package pack1;\n");
587
	  buf.append("\n");
588
	  buf.append("import pack2.A;\n");
589
	  buf.append("import pack2.A.Inner;\n");
590
	  buf.append("import pack2.B;\n");
591
	  buf.append("\n");
592
	  buf.append("public class C {\n");
593
	  buf.append("}\n");
594
595
      IPackageFragment pack1= this.sourceFolder.createPackageFragment("pack1", false, null);
596
	  ICompilationUnit cu= pack1.createCompilationUnit("C.java", buf.toString(), false, null);
597
598
	  // We need to actually make some state in the AST for the classes, to test that we can 
599
	  // disambiguate between packages and inner classes (see the bug for details).
600
	  IPackageFragment pack2= this.sourceFolder.createPackageFragment("pack2", false, null);
601
	  ICompilationUnit aUnit= pack2.createCompilationUnit("A.java", "", false, null);
602
	  ICompilationUnit bUnit= pack2.createCompilationUnit("B.java", "", false, null);
603
	  bUnit.createType("class B {}", null, false, null);
604
605
	  IType aType= aUnit.createType("class A {}", null, false, null);
606
	  aType.createType("class Inner {}", null, false, null);
607
	  String[] order= new String[] { "java" };
608
609
	  ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, false);
610
	  imports.addImport("pack2.A");
611
	  imports.addImport("pack2.B");
612
	  imports.addImport("pack2.A.Inner");
613
614
	  apply(imports);
615
616
	  buf= new StringBuffer();
617
	  buf.append("package pack1;\n");
618
	  buf.append("\n");
619
	  buf.append("import pack2.A;\n");
620
	  buf.append("import pack2.A.Inner;\n");
621
	  buf.append("import pack2.B;\n");
622
	  buf.append("\n");
623
	  buf.append("public class C {\n");
624
	  buf.append("}\n");
625
	  assertEqualString(cu.getSource(), buf.toString());
626
	}
627
628
	/**
629
	 * Test that a valid inner class import is not removed even when the container
630
	 * class is implicitly available. This tests the case where the classes are in 
631
	 * different compilation units.
632
	 * 
633
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=194358"
634
	 */
635
	public void testBug194358a() throws Exception {
636
	  StringBuffer buf= new StringBuffer();
637
	  buf.append("package com.pack1;\n");
638
	  buf.append("\n");
639
	  buf.append("import com.pack1.A;\n");
640
	  buf.append("import com.pack1.A.Inner;\n");
641
	  buf.append("import com.pack2.B;\n");
642
	  buf.append("\n");
643
	  buf.append("public class C {\n");
644
	  buf.append("}\n");
645
646
      IPackageFragment pack1= this.sourceFolder.createPackageFragment("com.pack1", false, null);
647
	  ICompilationUnit cu= pack1.createCompilationUnit("C.java", buf.toString(), false, null);
648
      ICompilationUnit aUnit= pack1.createCompilationUnit("A.java", "", false, null);
649
650
	  IPackageFragment pack2= this.sourceFolder.createPackageFragment("com.pack2", false, null);
651
      ICompilationUnit bUnit= pack2.createCompilationUnit("B.java", "", false, null);
652
	  bUnit.createType("class B {}", null, false, null);
653
	  IType aType= aUnit.createType("class A {}", null, false, null);
654
	  aType.createType("class Inner {}", null, false, null);
655
	  String[] order= new String[] { "java" };
656
657
	  ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, false);
658
	  imports.addImport("com.pack1.A");
659
	  imports.addImport("com.pack1.A.Inner");
660
	  imports.addImport("com.pack2.B");
661
662
	  apply(imports);
663
664
	  buf= new StringBuffer();
665
	  buf.append("package com.pack1;\n");
666
	  buf.append("\n");
667
	  buf.append("import com.pack1.A.Inner;\n");
668
	  buf.append("import com.pack2.B;\n");
669
	  buf.append("\n");
670
	  buf.append("public class C {\n");
671
	  buf.append("}\n");
672
	  assertEqualString(cu.getSource(), buf.toString());
673
	}
674
	/**
675
	 * Test that the Inner type imports are not removed while organizing even though the 
676
	 * containing class is implicitly available - for the case when both the classes are 
677
	 * in the same compilation unit
678
	 * 
679
	 * see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=235253"
680
	 */
681
	public void testBug235253() throws Exception {
682
		StringBuffer buf= new StringBuffer();
683
		buf.append("package bug;\n");
684
		buf.append("\n");
685
		buf.append("class Bug {\n");
686
		buf.append("public void addFile(File file) {}\n");
687
		buf.append("\tinterface Proto{};\n");
688
		buf.append("}\n");		
689
		buf.append("class Foo implements Proto{}");
690
691
		IPackageFragment pack1= this.sourceFolder.createPackageFragment("bug", false, null);
692
		ICompilationUnit cu= pack1.createCompilationUnit("Bug.java", buf.toString(), false, null);
693
		String[] order= new String[] { "bug" , "java" };
694
		ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, false);
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);
(-)ui/org/eclipse/jdt/ui/tests/core/AddImportTest.java (-1 / +8 lines)
Lines 93-98 Link Here
93
		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
93
		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
94
94
95
		IPackageFragment pack1= sourceFolder.createPackageFragment("pack1", false, null);
95
		IPackageFragment pack1= sourceFolder.createPackageFragment("pack1", false, null);
96
		
96
		StringBuffer buf= new StringBuffer();
97
		StringBuffer buf= new StringBuffer();
97
		buf.append("package pack1;\n");
98
		buf.append("package pack1;\n");
98
		buf.append("\n");
99
		buf.append("\n");
Lines 204-209 Link Here
204
205
205
	public void testRemoveImports1() throws Exception {
206
	public void testRemoveImports1() throws Exception {
206
		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
207
		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
208
		sourceFolder.createPackageFragment("java.util", false, null);
209
		sourceFolder.createPackageFragment("pack", false, null);
207
210
208
		IPackageFragment pack1= sourceFolder.createPackageFragment("pack1", false, null);
211
		IPackageFragment pack1= sourceFolder.createPackageFragment("pack1", false, null);
209
		StringBuffer buf= new StringBuffer();
212
		StringBuffer buf= new StringBuffer();
Lines 296-303 Link Here
296
		buf= new StringBuffer();
299
		buf= new StringBuffer();
297
		buf.append("package pack1;\n");
300
		buf.append("package pack1;\n");
298
		buf.append("\n");
301
		buf.append("\n");
299
		buf.append("import p.Inner;\n");
300
		buf.append("import p.A.*;\n");
302
		buf.append("import p.A.*;\n");
303
		buf.append("import p.Inner;\n");
301
		buf.append("\n");
304
		buf.append("\n");
302
		buf.append("public class C {\n");
305
		buf.append("public class C {\n");
303
		buf.append("}\n");
306
		buf.append("}\n");
Lines 308-313 Link Here
308
		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
311
		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
309
312
310
		IPackageFragment pack1= sourceFolder.createPackageFragment("pack1", false, null);
313
		IPackageFragment pack1= sourceFolder.createPackageFragment("pack1", false, null);
314
		sourceFolder.createPackageFragment("java.awt", false, null);
315
		sourceFolder.createPackageFragment("java.applet", false, null);
316
		sourceFolder.createPackageFragment("java.math", false, null);
317
		
311
		StringBuffer buf= new StringBuffer();
318
		StringBuffer buf= new StringBuffer();
312
		buf.append("package pack1;\n");
319
		buf.append("package pack1;\n");
313
		buf.append("\n");
320
		buf.append("\n");

Return to bug 194358