### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/internal/core/CompilationUnit.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java,v retrieving revision 1.242 diff -u -r1.242 CompilationUnit.java --- model/org/eclipse/jdt/internal/core/CompilationUnit.java 21 Sep 2007 13:16:47 -0000 1.242 +++ model/org/eclipse/jdt/internal/core/CompilationUnit.java 15 Jan 2008 16:05:50 -0000 @@ -12,6 +12,7 @@ *******************************************************************************/ package org.eclipse.jdt.internal.core; +import java.io.IOException; import java.util.*; import org.eclipse.core.resources.*; @@ -23,6 +24,7 @@ import org.eclipse.jdt.internal.compiler.SourceElementParser; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; import org.eclipse.jdt.internal.compiler.util.SuffixConstants; import org.eclipse.jdt.internal.core.util.MementoTokenizer; @@ -78,17 +80,10 @@ protected boolean buildStructure(OpenableElementInfo info, final IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info; - // get buffer contents + // ensure buffer is opened IBuffer buffer = getBufferManager().getBuffer(CompilationUnit.this); if (buffer == null) { - buffer = openBuffer(pm, unitInfo); // open buffer independently from the info, since we are building the info - } - final char[] contents; - if (buffer == null) { - contents = CharOperation.NO_CHAR ; - } else { - char[] characters = buffer.getCharacters(); - contents = characters == null ? CharOperation.NO_CHAR : characters; + openBuffer(pm, unitInfo); // open buffer independently from the info, since we are building the info } // generate structure and compute syntax problems if needed @@ -133,22 +128,6 @@ if (!computeProblems && !resolveBindings && !createAST) // disable javadoc parsing if not computing problems, not resolving and not creating ast parser.javadocParser.checkDocComment = false; requestor.parser = parser; - CompilationUnitDeclaration unit = parser.parseCompilationUnit( - new org.eclipse.jdt.internal.compiler.env.ICompilationUnit() { - public char[] getContents() { - return contents; - } - public char[] getMainTypeName() { - return CompilationUnit.this.getMainTypeName(); - } - public char[][] getPackageName() { - return CompilationUnit.this.getPackageName(); - } - public char[] getFileName() { - return CompilationUnit.this.getFileName(); - } - }, - true /*full parse to find local elements*/); // update timestamp (might be IResource.NULL_STAMP if original does not exist) if (underlyingResource == null) { @@ -160,12 +139,13 @@ // compute other problems if needed CompilationUnitDeclaration compilationUnitDeclaration = null; + CompilationUnit source = cloneCachingContents(); try { if (computeProblems) { if (problems == null) { // report problems to the problem requestor problems = new HashMap(); - compilationUnitDeclaration = CompilationUnitProblemFinder.process(unit, this, contents, parser, this.owner, problems, createAST, reconcileFlags, pm); + compilationUnitDeclaration = CompilationUnitProblemFinder.process(source, parser, this.owner, problems, createAST, reconcileFlags, pm); try { perWorkingCopyInfo.beginReporting(); for (Iterator iteraror = problems.values().iterator(); iteraror.hasNext();) { @@ -180,13 +160,15 @@ } } else { // collect problems - compilationUnitDeclaration = CompilationUnitProblemFinder.process(unit, this, contents, parser, this.owner, problems, createAST, reconcileFlags, pm); + compilationUnitDeclaration = CompilationUnitProblemFinder.process(source, parser, this.owner, problems, createAST, reconcileFlags, pm); } + } else { + compilationUnitDeclaration = parser.parseCompilationUnit(source, true /*full parse to find local elements*/); } if (createAST) { int astLevel = ((ASTHolderCUInfo) info).astLevel; - org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, unit, contents, options, computeProblems, this, reconcileFlags, pm); + org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, compilationUnitDeclaration, options, computeProblems, source, reconcileFlags, pm); ((ASTHolderCUInfo) info).ast = cu; } } finally { @@ -198,6 +180,20 @@ return unitInfo.isStructureKnown(); } /* + * Clone this handle so that it caches its contents in memory. + * DO NOT PASS TO CLIENTS + */ +public CompilationUnit cloneCachingContents() { + return new CompilationUnit((PackageFragment) this.parent, this.name, this.owner) { + private char[] cachedContents; + public char[] getContents() { + if (this.cachedContents == null) + this.cachedContents = CompilationUnit.this.getContents(); + return this.cachedContents; + } + }; +} +/* * @see Openable#canBeRemovedFromCache */ public boolean canBeRemovedFromCache() { @@ -587,15 +583,47 @@ if (buffer == null) { // no need to force opening of CU to get the content // also this cannot be a working copy, as its buffer is never closed while the working copy is alive + IFile file = (IFile) getResource(); + // Get encoding from file + String encoding; + try { + encoding = file.getCharset(); + } catch(CoreException ce) { + // do not use any encoding + encoding = null; + } try { - return Util.getResourceContentsAsCharArray((IFile) getResource()); + return Util.getResourceContentsAsCharArray(file, encoding); } catch (JavaModelException e) { + if (JavaModelManager.getJavaModelManager().abortOnMissingSource.get() == Boolean.TRUE) { + IOException ioException = + e.getJavaModelStatus().getCode() == IJavaModelStatusConstants.IO_EXCEPTION ? + (IOException)e.getException() : + new IOException(e.getMessage()); + throw new AbortCompilationUnit(null, ioException, encoding); + } else { + Util.log(e, Messages.bind(Messages.file_notFound, file.getFullPath().toString())); + } return CharOperation.NO_CHAR; } } char[] contents = buffer.getCharacters(); - if (contents == null) // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=129814 + if (contents == null) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=129814 + if (JavaModelManager.getJavaModelManager().abortOnMissingSource.get() == Boolean.TRUE) { + IOException ioException = new IOException(Messages.buffer_closed); + IFile file = (IFile) getResource(); + // Get encoding from file + String encoding; + try { + encoding = file.getCharset(); + } catch(CoreException ce) { + // do not use any encoding + encoding = null; + } + throw new AbortCompilationUnit(null, ioException, encoding); + } return CharOperation.NO_CHAR; + } return contents; } /** @@ -990,21 +1018,26 @@ public org.eclipse.jdt.core.dom.CompilationUnit makeConsistent(int astLevel, boolean resolveBindings, int reconcileFlags, HashMap problems, IProgressMonitor monitor) throws JavaModelException { if (isConsistent()) return null; - // create a new info and make it the current info - // (this will remove the info and its children just before storing the new infos) - if (astLevel != NO_AST || problems != null) { - ASTHolderCUInfo info = new ASTHolderCUInfo(); - info.astLevel = astLevel; - info.resolveBindings = resolveBindings; - info.reconcileFlags = reconcileFlags; - info.problems = problems; - openWhenClosed(info, monitor); - org.eclipse.jdt.core.dom.CompilationUnit result = info.ast; - info.ast = null; - return result; - } else { - openWhenClosed(createElementInfo(), monitor); - return null; + try { + JavaModelManager.getJavaModelManager().abortOnMissingSource.set(Boolean.TRUE); + // create a new info and make it the current info + // (this will remove the info and its children just before storing the new infos) + if (astLevel != NO_AST || problems != null) { + ASTHolderCUInfo info = new ASTHolderCUInfo(); + info.astLevel = astLevel; + info.resolveBindings = resolveBindings; + info.reconcileFlags = reconcileFlags; + info.problems = problems; + openWhenClosed(info, monitor); + org.eclipse.jdt.core.dom.CompilationUnit result = info.ast; + info.ast = null; + return result; + } else { + openWhenClosed(createElementInfo(), monitor); + return null; + } + } finally { + JavaModelManager.getJavaModelManager().abortOnMissingSource.set(null); } } /** Index: model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java,v retrieving revision 1.47 diff -u -r1.47 ReconcileWorkingCopyOperation.java --- model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java 22 Nov 2007 11:24:43 -0000 1.47 +++ model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java 15 Jan 2008 16:05:51 -0000 @@ -177,19 +177,18 @@ return this.ast; // no need to recompute AST if known already CompilationUnitDeclaration unit = null; - char[] contents = null; try { + JavaModelManager.getJavaModelManager().abortOnMissingSource.set(Boolean.TRUE); + CompilationUnit source = workingCopy.cloneCachingContents(); // find problems if needed if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject()) && (this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) { this.resolveBindings = this.requestorIsActive; if (this.problems == null) this.problems = new HashMap(); - contents = workingCopy.getContents(); unit = CompilationUnitProblemFinder.process( - workingCopy, - contents, + source, this.workingCopyOwner, this.problems, this.astLevel != ICompilationUnit.NO_AST/*creating AST if level is not NO_AST */, @@ -207,10 +206,9 @@ AST.convertCompilationUnit( this.astLevel, unit, - contents, options, this.resolveBindings, - workingCopy, + source, reconcileFlags, this.progressMonitor); if (this.ast != null) { @@ -227,6 +225,7 @@ // else JavaProject has lost its nature (or most likely was closed/deleted) while reconciling -> ignore // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=100919) } finally { + JavaModelManager.getJavaModelManager().abortOnMissingSource.set(null); if (unit != null) { unit.cleanUp(); } Index: model/org/eclipse/jdt/internal/core/JavaModelManager.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java,v retrieving revision 1.381 diff -u -r1.381 JavaModelManager.java --- model/org/eclipse/jdt/internal/core/JavaModelManager.java 4 Dec 2007 11:10:12 -0000 1.381 +++ model/org/eclipse/jdt/internal/core/JavaModelManager.java 15 Jan 2008 16:05:51 -0000 @@ -404,6 +404,9 @@ public final CompilationParticipants compilationParticipants = new CompilationParticipants(); + /* whether an AbortCompilationUnit should be thrown when the source of a compilation unit cannot be retrieved */ + public ThreadLocal abortOnMissingSource = new ThreadLocal(); + /** * Returns whether the given full path (for a package) conflicts with the output location * of the given project. Index: model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java,v retrieving revision 1.58 diff -u -r1.58 CompilationUnitProblemFinder.java --- model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java 16 Mar 2007 18:28:58 -0000 1.58 +++ model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java 15 Jan 2008 16:05:50 -0000 @@ -25,8 +25,8 @@ import org.eclipse.jdt.internal.compiler.env.ISourceType; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; -import org.eclipse.jdt.internal.compiler.parser.Parser; import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter; +import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; import org.eclipse.jdt.internal.core.util.CommentRecorderParser; import org.eclipse.jdt.internal.core.util.Util; @@ -141,10 +141,8 @@ } public static CompilationUnitDeclaration process( - CompilationUnitDeclaration unit, - ICompilationUnit unitElement, - char[] contents, - Parser parser, + CompilationUnit unitElement, + SourceElementParser parser, WorkingCopyOwner workingCopyOwner, HashMap problems, boolean creatingAST, @@ -165,31 +163,27 @@ getCompilerOptions(project.getOptions(true), creatingAST, ((reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0)), getRequestor(), problemFactory); + CompilationUnitDeclaration unit = null; if (parser != null) { problemFinder.parser = parser; - } - PackageFragment packageFragment = (PackageFragment)unitElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT); - char[][] expectedPackageName = null; - if (packageFragment != null){ - expectedPackageName = Util.toCharArrays(packageFragment.names); - } - if (unit == null) { - unit = problemFinder.resolve( - new BasicCompilationUnit( - contents, - expectedPackageName, - unitElement.getPath().toString(), - unitElement), - true, // verify methods - true, // analyze code - true); // generate code + try { + unit = parser.parseCompilationUnit(unitElement, true/*full parse*/); + problemFinder.resolve( + unit, + unitElement, + true, // verify methods + true, // analyze code + true); // generate code + } catch (AbortCompilation e) { + problemFinder.handleInternalException(e, unit); + } } else { - problemFinder.resolve( - unit, - null, // no need for source - true, // verify methods - true, // analyze code - true); // generate code + unit = + problemFinder.resolve( + unitElement, + true, // verify methods + true, // analyze code + true); // generate code } CompilationResult unitResult = unit.compilationResult; CategorizedProblem[] unitProblems = unitResult.getProblems(); @@ -220,7 +214,7 @@ message.append(lineDelimiter); message.append("----------------------------------- SOURCE BEGIN -------------------------------------"); //$NON-NLS-1$ message.append(lineDelimiter); - message.append(contents); + message.append(unitElement.getSource()); message.append(lineDelimiter); message.append("----------------------------------- SOURCE END -------------------------------------"); //$NON-NLS-1$ Util.log(e, message.toString()); @@ -237,8 +231,7 @@ } public static CompilationUnitDeclaration process( - ICompilationUnit unitElement, - char[] contents, + CompilationUnit unitElement, WorkingCopyOwner workingCopyOwner, HashMap problems, boolean creatingAST, @@ -246,7 +239,7 @@ IProgressMonitor monitor) throws JavaModelException { - return process(null/*no CompilationUnitDeclaration*/, unitElement, contents, null/*use default Parser*/, workingCopyOwner, problems, creatingAST, reconcileFlags, monitor); + return process(unitElement, null/*use default Parser*/, workingCopyOwner, problems, creatingAST, reconcileFlags, monitor); } /* (non-Javadoc) Index: dom/org/eclipse/jdt/core/dom/AST.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java,v retrieving revision 1.156 diff -u -r1.156 AST.java --- dom/org/eclipse/jdt/core/dom/AST.java 21 Mar 2007 17:51:08 -0000 1.156 +++ dom/org/eclipse/jdt/core/dom/AST.java 15 Jan 2008 16:05:49 -0000 @@ -242,7 +242,6 @@ * * @param level the API level; one of the LEVEL constants * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration - * @param source the string of the Java compilation unit * @param options compiler options * @param workingCopy the working copy that the AST is created from * @param monitor the progress monitor used to report progress and request cancelation, @@ -253,7 +252,6 @@ public static CompilationUnit convertCompilationUnit( int level, org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration, - char[] source, Map options, boolean isResolved, org.eclipse.jdt.internal.core.CompilationUnit workingCopy, @@ -275,7 +273,7 @@ ast.setBindingResolver(resolver); converter.setAST(ast); - CompilationUnit unit = converter.convert(compilationUnitDeclaration, source); + CompilationUnit unit = converter.convert(compilationUnitDeclaration, workingCopy.getContents()); unit.setLineEndTable(compilationUnitDeclaration.compilationResult.getLineSeparatorPositions()); unit.setTypeRoot(workingCopy); ast.setDefaultNodeFlag(savedDefaultNodeFlag); Index: model/org/eclipse/jdt/internal/compiler/SourceElementParser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java,v retrieving revision 1.80 diff -u -r1.80 SourceElementParser.java --- model/org/eclipse/jdt/internal/compiler/SourceElementParser.java 30 Nov 2007 11:48:29 -0000 1.80 +++ model/org/eclipse/jdt/internal/compiler/SourceElementParser.java 15 Jan 2008 16:05:50 -0000 @@ -1512,12 +1512,12 @@ boolean fullParse) { boolean old = diet; - + CompilationUnitDeclaration parsedUnit = null; try { diet = true; this.reportReferenceInfo = fullParse; CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit); - CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult); + parsedUnit = parse(unit, compilationUnitResult); if (scanner.recordLineSeparator) { requestor.acceptLineSeparatorPositions(compilationUnitResult.getLineSeparatorPositions()); } @@ -1536,7 +1536,7 @@ diet = old; reset(); } - return null; + return parsedUnit; } public void parseTypeMemberDeclarations( ISourceType type, Index: model/org/eclipse/jdt/internal/core/util/Util.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java,v retrieving revision 1.114 diff -u -r1.114 Util.java --- model/org/eclipse/jdt/internal/core/util/Util.java 11 Jan 2008 12:42:51 -0000 1.114 +++ model/org/eclipse/jdt/internal/core/util/Util.java 15 Jan 2008 16:05:51 -0000 @@ -1050,7 +1050,7 @@ throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Messages.bind(Messages.file_notFound, file.getFullPath().toString()))); length = EFS.getStore(locationURI).fetchInfo().getLength(); } catch (CoreException e) { - throw new JavaModelException(e); + throw new JavaModelException(e, IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST); } } else { // local file Index: model/org/eclipse/jdt/internal/core/util/messages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties,v retrieving revision 1.69 diff -u -r1.69 messages.properties --- model/org/eclipse/jdt/internal/core/util/messages.properties 15 Jan 2008 10:01:31 -0000 1.69 +++ model/org/eclipse/jdt/internal/core/util/messages.properties 15 Jan 2008 16:05:51 -0000 @@ -170,6 +170,7 @@ classpath_deprecated_variable = Classpath variable ''{0}'' in project ''{1}'' is deprecated: {2} ### miscellaneous +buffer_closed=Buffer is closed file_notFound = File not found: ''{0}'' file_badFormat = Bad format path_nullPath = Path cannot be null Index: model/org/eclipse/jdt/internal/core/util/Messages.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java,v retrieving revision 1.19 diff -u -r1.19 Messages.java --- model/org/eclipse/jdt/internal/core/util/Messages.java 19 Oct 2007 15:57:22 -0000 1.19 +++ model/org/eclipse/jdt/internal/core/util/Messages.java 15 Jan 2008 16:05:51 -0000 @@ -74,6 +74,7 @@ public static String operation_pathOutsideProject; public static String operation_sortelements; public static String workingCopy_commit; + public static String buffer_closed; public static String build_preparingBuild; public static String build_readStateProgress; public static String build_saveStateProgress; #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/TestBuffer.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TestBuffer.java,v retrieving revision 1.7 diff -u -r1.7 TestBuffer.java --- src/org/eclipse/jdt/core/tests/model/TestBuffer.java 10 May 2006 18:54:11 -0000 1.7 +++ src/org/eclipse/jdt/core/tests/model/TestBuffer.java 15 Jan 2008 16:05:54 -0000 @@ -44,6 +44,7 @@ */ public void append(char[] text) { this.hasUnsavedChanges = true; + notifyListeners(); } /* @@ -51,6 +52,7 @@ */ public void append(String text) { this.hasUnsavedChanges = true; + notifyListeners(); } /* @@ -59,15 +61,19 @@ public void close() { this.contents = null; // mark as closed if (this.changeListeners != null) { - BufferChangedEvent event = null; - event = new BufferChangedEvent(this, 0, 0, null); - for (int i = 0, size = this.changeListeners.size(); i < size; ++i) { - IBufferChangedListener listener = (IBufferChangedListener) this.changeListeners.get(i); - listener.bufferChanged(event); - } + notifyListeners(); this.changeListeners = null; } } + private void notifyListeners() { + if (this.changeListeners == null) return; + BufferChangedEvent event = null; + event = new BufferChangedEvent(this, 0, 0, null); + for (int i = 0, size = this.changeListeners.size(); i < size; ++i) { + IBufferChangedListener listener = (IBufferChangedListener) this.changeListeners.get(i); + listener.bufferChanged(event); + } + } /* * @see IBuffer#getChar(int) @@ -156,6 +162,7 @@ */ public void replace(int position, int length, char[] text) { this.hasUnsavedChanges = true; + notifyListeners(); } /* @@ -163,6 +170,7 @@ */ public void replace(int position, int length, String text) { this.hasUnsavedChanges = true; + notifyListeners(); } /* @@ -178,6 +186,7 @@ public void setContents(char[] characters) { this.contents = characters; this.hasUnsavedChanges = true; + notifyListeners(); } /* @@ -186,6 +195,7 @@ public void setContents(String characters) { this.contents = characters.toCharArray(); this.hasUnsavedChanges = true; + notifyListeners(); } } Index: src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java,v retrieving revision 1.123 diff -u -r1.123 ReconcilerTests.java --- src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java 9 Jan 2008 11:17:32 -0000 1.123 +++ src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java 15 Jan 2008 16:05:54 -0000 @@ -105,6 +105,17 @@ protected void assertProblems(String message, String expected) { assertProblems(message, expected, this.problemRequestor); } +protected void assertProblemsInclude(String message, String expected) { + String actual = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(problemRequestor.problems.toString()); + String independantExpectedString = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(expected); + if (actual.indexOf(independantExpectedString) == -1){ + System.out.println(org.eclipse.jdt.core.tests.util.Util.displayString(actual, this.tabs)); + assertEquals( + message, + independantExpectedString, + actual); + } +} // Expect no error as soon as indexing is finished protected void assertNoProblem(char[] source, ICompilationUnit unit) throws InterruptedException, JavaModelException { IndexManager indexManager = JavaModelManager.getIndexManager(); @@ -813,6 +824,84 @@ deleteFile("/Reconciler/src/p1/Super.java"); } } +/* + * Ensures that reconciling with a closed buffer reports an error + * (regression test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=138882 ) + */ +public void testBufferClosed1() throws CoreException { + this.wcOwner = new WorkingCopyOwner() { + public IBuffer createBuffer(ICompilationUnit copy) { + return new TestBuffer(copy); + } + public IProblemRequestor getProblemRequestor(ICompilationUnit unit) { + return ReconcilerTests.this.problemRequestor; + } + }; + setUpWorkingCopy( + "Reconciler/src/p1/X.java", + "package p1;\n" + + "public class X {\n" + + " void foo(String s) {\n" + + " }\n" + + "}" + ); + + // simulate buffer being closed + ((TestBuffer) this.workingCopy.getBuffer()).contents = null; + + this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null); + assertProblemsInclude( + "Unexpected problems", + "----------\n" + + "1. ERROR in /Reconciler/src/p1/X.java (at line 1)\n" + + " package p1;\n" + + " ^\n" + + "Cannot read the source from /Reconciler/src/p1/X.java due to internal exception java.io.IOException:Buffer is closed\n" + + "----------\n" + ); +} +/* + * Ensures that reconciling with a closed buffer reports an error + * (regression test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=138882 ) + */ +public void testBufferClosed2() throws CoreException { + this.wcOwner = new WorkingCopyOwner() { + public IBuffer createBuffer(ICompilationUnit copy) { + return new TestBuffer(copy); + } + public IProblemRequestor getProblemRequestor(ICompilationUnit unit) { + return ReconcilerTests.this.problemRequestor; + } + }; + setUpWorkingCopy( + "Reconciler/src/p1/X.java", + "package p1;\n" + + "public class X {\n" + + " void foo(String s) {\n" + + " }\n" + + "}" + ); + // make the working copy not consistent + setWorkingCopyContents( + "package p1;\n" + + "public class X {\n" + + "}" + ); + + // simulate buffer being closed + ((TestBuffer) this.workingCopy.getBuffer()).contents = null; + + this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null); + assertProblemsInclude( + "Unexpected problems", + "----------\n" + + "1. ERROR in /Reconciler/src/p1/X.java (at line 1)\n" + + " package p1;\n" + + " ^\n" + + "Cannot read the source from /Reconciler/src/p1/X.java due to internal exception java.io.IOException:Buffer is closed\n" + + "----------\n" + ); +} /** * Ensure an OperationCanceledException is correcly thrown when progress monitor is canceled * @deprecated using deprecated code Index: src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java,v retrieving revision 1.58 diff -u -r1.58 CompilationUnitTests.java --- src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java 11 Jan 2008 12:42:49 -0000 1.58 +++ src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java 15 Jan 2008 16:05:54 -0000 @@ -14,10 +14,15 @@ import java.net.URI; import java.net.URISyntaxException; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.core.*; import org.eclipse.jdt.internal.core.*; import org.eclipse.jdt.internal.core.util.Util; @@ -349,6 +354,34 @@ } /* + * Ensures that retrieving the content of a compilation whose file has been deleted logs the problem + * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=138882 ) + */ +public void testFileDeleted() throws CoreException { + ILog log = JavaCore.getPlugin().getLog(); + ILogListener listener = new ILogListener(){ + private StringBuffer buffer = new StringBuffer(); + public void logging(IStatus status, String plugin) { + buffer.append(status); + buffer.append('\n'); + } + public String toString() { + return this.buffer.toString(); + } + }; + try { + log.addLogListener(listener); + ((org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getCompilationUnit("/P/src/p/Deleted.java")).getContents(); + assertSourceEquals( + "Unexpected error logged", + "Status ERROR: org.eclipse.jdt.core code=4 File not found: \'/P/src/p/Deleted.java\' org.eclipse.core.internal.resources.ResourceException: Resource \'/P/src/p/Deleted.java\' does not exist.\n", + listener.toString()); + } finally { + log.removeLogListener(listener); + } +} + +/* * Ensures that findPrimaryType() doesn't throw an exception if the cu name is invalid. * (regression test for bug 120865 ICompilationUnit.findPrimaryType(..) should not throw internal AFE) */