Index: src/org/eclipse/jdt/core/tests/builder/DependencyTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/DependencyTests.java,v retrieving revision 1.26 diff -u -r1.26 DependencyTests.java --- src/org/eclipse/jdt/core/tests/builder/DependencyTests.java 9 Apr 2007 17:34:49 -0000 1.26 +++ src/org/eclipse/jdt/core/tests/builder/DependencyTests.java 11 May 2007 17:13:22 -0000 @@ -67,6 +67,53 @@ expectingOnlySpecificProblemFor(collaboratorPath, new Problem("Collaborator", "The type Collaborator must implement the inherited abstract method Indicted.foo()", collaboratorPath, 38, 50, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$ } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=168208 + public void testCaseInvariantType() throws JavaModelException { + IPath projectPath = env.addProject("Project"); //$NON-NLS-1$ + env.addExternalJars(projectPath, Util.getJavaClassLibs()); + + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$ + + IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$ + env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ + + org.eclipse.jdt.core.IJavaProject p = env.getJavaProject("Project"); + java.util.Map options = p.getOptions(true); + options.put(org.eclipse.jdt.core.JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, org.eclipse.jdt.core.JavaCore.DISABLED); //$NON-NLS-1$ + p.setOptions(options); + + env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$ + "package p1;\n"+ //$NON-NLS-1$ + "public class A {\n" + + " class Node {}\n" + + "}" //$NON-NLS-1$ + ); + + env.addClass(root, "p1", "Bb", //$NON-NLS-1$ //$NON-NLS-2$ + "package p1;\n"+ //$NON-NLS-1$ + "class Bb {}" //$NON-NLS-1$ + ); + + fullBuild(projectPath); + expectingNoProblems(); + + env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$ + "package p1;\n"+ //$NON-NLS-1$ + "public class A {\n" + + " class node {}\n" + + "}" //$NON-NLS-1$ + ); + + env.addClass(root, "p1", "Bb", //$NON-NLS-1$ //$NON-NLS-2$ + "package p1;\n"+ //$NON-NLS-1$ + "class BB {}" //$NON-NLS-1$ + ); + + incrementalBuild(projectPath); + expectingNoProblems(); + } + public void testExactMethodDeleting() throws JavaModelException { IPath projectPath = env.addProject("Project"); //$NON-NLS-1$ env.addExternalJars(projectPath, Util.getJavaClassLibs()); Index: model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java,v retrieving revision 1.94 diff -u -r1.94 IncrementalImageBuilder.java --- model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java 9 Apr 2007 17:34:50 -0000 1.94 +++ model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java 11 May 2007 17:13:24 -0000 @@ -776,11 +776,11 @@ storeTasksFor(sourceFile, tasks); } -protected void writeClassFileBytes(byte[] bytes, IFile file, String qualifiedFileName, boolean isTopLevelType, boolean updateClassFile) throws CoreException { +protected void writeClassFileBytes(byte[] bytes, IFile file, String qualifiedFileName, boolean isTopLevelType, SourceFile compilationUnit) throws CoreException { // Before writing out the class file, compare it to the previous file - // If structural changes occured then add dependent source files + // If structural changes occurred then add dependent source files if (file.exists()) { - if (writeClassFileCheck(file, qualifiedFileName, bytes) || updateClassFile) { // see 46093 + if (writeClassFileCheck(file, qualifiedFileName, bytes) || compilationUnit.updateClassFile) { // see 46093 if (JavaBuilder.DEBUG) System.out.println("Writing changed class file " + file.getName());//$NON-NLS-1$ if (!file.isDerived()) @@ -797,9 +797,40 @@ try { file.create(new ByteArrayInputStream(bytes), IResource.FORCE | IResource.DERIVED, null); } catch (CoreException e) { - if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) - // catch the case that a nested type has been renamed and collides on disk with an as-yet-to-be-deleted type + if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) { + IStatus status = e.getStatus(); + if (status instanceof IResourceStatus) { + IPath oldFilePath = ((IResourceStatus) status).getPath(); + char[] oldTypeName = oldFilePath.removeFileExtension().lastSegment().toCharArray(); + char[][] previousTypeNames = newState.getDefinedTypeNamesFor(compilationUnit.typeLocator()); + boolean fromSameFile = false; + if (previousTypeNames == null) { + fromSameFile = CharOperation.equals(compilationUnit.getMainTypeName(), oldTypeName); + } else { + for (int i = 0, l = previousTypeNames.length; i < l; i++) { + if (CharOperation.equals(previousTypeNames[i], oldTypeName)) { + fromSameFile = true; + break; + } + } + } + if (fromSameFile) { + // file is defined by the same compilationUnit, but won't be deleted until later so do it now + IFile collision = file.getParent().getFile(new Path(oldFilePath.lastSegment())); + collision.delete(true, false, null); + boolean success = false; + try { + file.create(new ByteArrayInputStream(bytes), IResource.FORCE | IResource.DERIVED, null); + success = true; + } catch (CoreException ignored) { + // ignore the second exception + } + if (success) return; + } + } + // catch the case that a type has been renamed and collides on disk with an as-yet-to-be-deleted type throw new AbortCompilation(true, new AbortIncrementalBuildException(qualifiedFileName)); + } throw e; // rethrow } } Index: model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java,v retrieving revision 1.111 diff -u -r1.111 AbstractImageBuilder.java --- model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java 7 May 2007 19:28:13 -0000 1.111 +++ model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java 11 May 2007 17:13:24 -0000 @@ -788,7 +788,7 @@ } IFile file = container.getFile(filePath.addFileExtension(SuffixConstants.EXTENSION_class)); - writeClassFileBytes(classFile.getBytes(), file, fileName, isTopLevelType, compilationUnit.updateClassFile); + writeClassFileBytes(classFile.getBytes(), file, fileName, isTopLevelType, compilationUnit); if (classFile.isShared) { this.compiler.lookupEnvironment.classFilePool.release(classFile); } @@ -796,7 +796,7 @@ return filePath.lastSegment().toCharArray(); } -protected void writeClassFileBytes(byte[] bytes, IFile file, String qualifiedFileName, boolean isTopLevelType, boolean updateClassFile) throws CoreException { +protected void writeClassFileBytes(byte[] bytes, IFile file, String qualifiedFileName, boolean isTopLevelType, SourceFile compilationUnit) throws CoreException { if (file.exists()) { // Deal with shared output folders... last one wins... no collision cases detected if (JavaBuilder.DEBUG)