blob: acb35f4747884fc8731fe5039bdcbbddb8420af6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.core.tests.model;
import junit.framework.Test;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
public class ReconcilerStatementsRecoveryTests extends ModifyingResourceTests {
protected ICompilationUnit workingCopy;
protected ProblemRequestor problemRequestor;
/* A problem requestor that auto-cancels on first problem */
class CancelingProblemRequestor extends ProblemRequestor {
IProgressMonitor progressMonitor = new IProgressMonitor() {
boolean isCanceled = false;
public void beginTask(String name, int totalWork) {}
public void done() {}
public void internalWorked(double work) {}
public boolean isCanceled() {
return this.isCanceled;
}
public void setCanceled(boolean value) {
this.isCanceled = value;
}
public void setTaskName(String name) {}
public void subTask(String name) {}
public void worked(int work) {}
};
boolean isCanceling = false;
public void acceptProblem(IProblem problem) {
if (this.isCanceling) this.progressMonitor.setCanceled(true); // auto-cancel on first problem
super.acceptProblem(problem);
}
}
/**
*/
public ReconcilerStatementsRecoveryTests(String name) {
super(name);
}
// Use this static initializer to specify subset for tests
// All specified tests which do not belong to the class are skipped...
static {
// JavaModelManager.VERBOSE = true;
// org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true;
// TESTS_PREFIX = "testIgnoreIfBetterNonAccessibleRule";
// TESTS_NAMES = new String[] { "testExternal" };
// TESTS_NUMBERS = new int[] { 118823 };
// TESTS_RANGE = new int[] { 16, -1 };
}
public static Test suite() {
return buildModelTestSuite(ReconcilerStatementsRecoveryTests.class);
}
protected void assertProblems(String message, String expected) {
assertProblems(message, expected, this.problemRequestor);
}
// Expect no error as soon as indexing is finished
protected void assertNoProblem(char[] source, ICompilationUnit unit) throws InterruptedException, JavaModelException {
IndexManager indexManager = JavaModelManager.getIndexManager();
if (this.problemRequestor.problemCount > 0) {
// If errors then wait for indexes to finish
while (indexManager.awaitingJobsCount() > 0) {
Thread.sleep(100);
}
// Reconcile again to see if error goes away
this.problemRequestor.initialize(source);
unit.getBuffer().setContents(source); // need to set contents again to be sure that following reconcile will be really done
unit.reconcile(AST.JLS3,
true, // force problem detection to see errors if any
null, // do not use working copy owner to not use working copies in name lookup
null);
if (this.problemRequestor.problemCount > 0) {
assertEquals("Working copy should NOT have any problem!", "", this.problemRequestor.problems.toString());
}
}
}
protected void addClasspathEntries(IClasspathEntry[] entries, boolean enableForbiddenReferences) throws JavaModelException {
IJavaProject project = getJavaProject("Reconciler");
IClasspathEntry[] oldClasspath = project.getRawClasspath();
int oldLength = oldClasspath.length;
int length = entries.length;
IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+length];
System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
System.arraycopy(entries, 0, newClasspath, oldLength, length);
project.setRawClasspath(newClasspath, null);
if (enableForbiddenReferences) {
project.setOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, JavaCore.ERROR);
}
}
protected void removeClasspathEntries(IClasspathEntry[] entries) throws JavaModelException {
IJavaProject project = getJavaProject("Reconciler");
IClasspathEntry[] oldClasspath = project.getRawClasspath();
int oldLength = oldClasspath.length;
int length = entries.length;
IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength-length];
System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength-length);
project.setRawClasspath(newClasspath, null);
}
/**
* Setup for the next test.
*/
public void setUp() throws Exception {
super.setUp();
this.problemRequestor = new ProblemRequestor();
this.workingCopy = getCompilationUnit("Reconciler/src/p1/X.java").getWorkingCopy(newWorkingCopyOwner(this.problemRequestor), null);
this.problemRequestor.initialize(this.workingCopy.getSource().toCharArray());
startDeltas();
}
public void setUpSuite() throws Exception {
super.setUpSuite();
// Create project with 1.4 compliance
IJavaProject project14 = createJavaProject("Reconciler", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
createFolder("/Reconciler/src/p1");
createFolder("/Reconciler/src/p2");
createFile(
"/Reconciler/src/p1/X.java",
"package p1;\n" +
"import p2.*;\n" +
"public class X {\n" +
" public void foo() {\n" +
" }\n" +
"}"
);
project14.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.IGNORE);
project14.setOption(JavaCore.COMPILER_PB_INVALID_JAVADOC, JavaCore.WARNING);
// Create project with 1.5 compliance
IJavaProject project15 = createJavaProject("Reconciler15", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5");
addLibrary(
project15,
"lib15.jar",
"lib15src.zip",
new String[] {
"java/util/List.java",
"package java.util;\n" +
"public class List<T> {\n" +
"}",
"java/util/Stack.java",
"package java.util;\n" +
"public class Stack<T> {\n" +
"}",
"java/util/Map.java",
"package java.util;\n" +
"public interface Map<K,V> {\n" +
"}",
"java/lang/annotation/Annotation.java",
"package java.lang.annotation;\n" +
"public interface Annotation {\n" +
"}",
"java/lang/Deprecated.java",
"package java.lang;\n" +
"public @interface Deprecated {\n" +
"}",
"java/lang/SuppressWarnings.java",
"package java.lang;\n" +
"public @interface SuppressWarnings {\n" +
" String[] value();\n" +
"}"
},
JavaCore.VERSION_1_5
);
project15.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.IGNORE);
}
//private void setUp15WorkingCopy() throws JavaModelException {
// setUp15WorkingCopy("Reconciler15/src/p1/X.java", new WorkingCopyOwner() {});
//}
//private void setUp15WorkingCopy(String path, WorkingCopyOwner owner) throws JavaModelException {
// String contents = this.workingCopy.getSource();
// setUpWorkingCopy(path, contents, owner);
//}
//private void setUpWorkingCopy(String path, String contents) throws JavaModelException {
// setUpWorkingCopy(path, contents, new WorkingCopyOwner() {});
//}
//private void setUpWorkingCopy(String path, String contents, WorkingCopyOwner owner) throws JavaModelException {
// this.workingCopy.discardWorkingCopy();
// this.workingCopy = getCompilationUnit(path).getWorkingCopy(owner, this.problemRequestor, null);
// setWorkingCopyContents(contents);
// this.workingCopy.makeConsistent(null);
//}
void setWorkingCopyContents(String contents) throws JavaModelException {
this.workingCopy.getBuffer().setContents(contents);
this.problemRequestor.initialize(contents.toCharArray());
}
/**
* Cleanup after the previous test.
*/
public void tearDown() throws Exception {
TestCompilationParticipant.PARTICIPANT = null;
if (this.workingCopy != null) {
this.workingCopy.discardWorkingCopy();
}
stopDeltas();
super.tearDown();
}
public void tearDownSuite() throws Exception {
deleteProject("Reconciler");
deleteProject("Reconciler15");
super.tearDownSuite();
}
/*
* No ast and no statements recovery
*/
public void testStatementsRecovery01() throws CoreException {
// Introduce syntax error
setWorkingCopyContents(
"package p1;\n" +
"import p2.*;\n" +
"public class X {\n" +
" public void foo() {\n" +
" UnknownType name\n" +
" }\n" +
"}");
this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, false, null, null);
assertWorkingCopyDeltas(
"Unexpected delta after syntax error",
"[Working copy] X.java[*]: {CONTENT | FINE GRAINED}"
);
assertProblems(
"Unexpected problems",
"----------\n" +
"1. ERROR in /Reconciler/src/p1/X.java (at line 5)\n" +
" UnknownType name\n" +
" ^^^^\n" +
"Syntax error, insert \";\" to complete BlockStatements\n" +
"----------\n"
);
clearDeltas();
}
/*
* Ast and no statements recovery
*/
public void testStatementsRecovery02() throws CoreException {
// Introduce syntax error
setWorkingCopyContents(
"package p1;\n" +
"import p2.*;\n" +
"public class X {\n" +
" public void foo() {\n" +
" UnknownType name\n" +
" }\n" +
"}");
this.workingCopy.reconcile(AST.JLS3, false, false, null, null);
assertWorkingCopyDeltas(
"Unexpected delta after syntax error",
"[Working copy] X.java[*]: {CONTENT | FINE GRAINED | AST AFFECTED}"
);
assertProblems(
"Unexpected problems",
"----------\n" +
"1. ERROR in /Reconciler/src/p1/X.java (at line 5)\n" +
" UnknownType name\n" +
" ^^^^\n" +
"Syntax error, insert \";\" to complete BlockStatements\n" +
"----------\n"
);
clearDeltas();
}
/*
* No ast, statements recovery
*/
public void testStatementsRecovery03() throws CoreException {
// Introduce syntax error
setWorkingCopyContents(
"package p1;\n" +
"import p2.*;\n" +
"public class X {\n" +
" public void foo() {\n" +
" UnknownType name\n" +
" }\n" +
"}");
this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, true, null, null);
assertWorkingCopyDeltas(
"Unexpected delta after syntax error",
"[Working copy] X.java[*]: {CONTENT | FINE GRAINED}"
);
assertProblems(
"Unexpected problems",
"----------\n" +
"1. ERROR in /Reconciler/src/p1/X.java (at line 5)\n" +
" UnknownType name\n" +
" ^^^^^^^^^^^\n" +
"UnknownType cannot be resolved to a type\n" +
"----------\n" +
"2. ERROR in /Reconciler/src/p1/X.java (at line 5)\n" +
" UnknownType name\n" +
" ^^^^\n" +
"Syntax error, insert \";\" to complete BlockStatements\n" +
"----------\n"
);
clearDeltas();
}
/*
* Ast, statements recovery
*/
public void testStatementsRecovery04() throws CoreException {
// Introduce syntax error
setWorkingCopyContents(
"package p1;\n" +
"import p2.*;\n" +
"public class X {\n" +
" public void foo() {\n" +
" UnknownType name\n" +
" }\n" +
"}");
this.workingCopy.reconcile(AST.JLS3, false, true, null, null);
assertWorkingCopyDeltas(
"Unexpected delta after syntax error",
"[Working copy] X.java[*]: {CONTENT | FINE GRAINED | AST AFFECTED}"
);
assertProblems(
"Unexpected problems",
"----------\n" +
"1. ERROR in /Reconciler/src/p1/X.java (at line 5)\n" +
" UnknownType name\n" +
" ^^^^^^^^^^^\n" +
"UnknownType cannot be resolved to a type\n" +
"----------\n" +
"2. ERROR in /Reconciler/src/p1/X.java (at line 5)\n" +
" UnknownType name\n" +
" ^^^^\n" +
"Syntax error, insert \";\" to complete BlockStatements\n" +
"----------\n"
);
clearDeltas();
}
}