| /******************************************************************************* |
| * Copyright (c) 2000, 2014 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 java.io.File; |
| import java.io.IOException; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.Map; |
| |
| import junit.framework.Test; |
| |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRunnable; |
| import org.eclipse.core.resources.IncrementalProjectBuilder; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.ILogListener; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.jdt.core.*; |
| import org.eclipse.jdt.core.compiler.CategorizedProblem; |
| import org.eclipse.jdt.core.compiler.CompilationParticipant; |
| import org.eclipse.jdt.core.compiler.IProblem; |
| import org.eclipse.jdt.core.compiler.ReconcileContext; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.tests.util.Util; |
| import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
| import org.eclipse.jdt.internal.core.CompilationUnit; |
| import org.eclipse.jdt.internal.core.JavaModelManager; |
| import org.eclipse.jdt.internal.core.search.indexing.IndexManager; |
| |
| public class ReconcilerTests extends ModifyingResourceTests { |
| |
| protected ICompilationUnit workingCopy; |
| protected ProblemRequestor problemRequestor; |
| |
| /* A problem requestor that auto-cancels on first problem */ |
| static 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); |
| } |
| } |
| |
| /** |
| * Internal synonynm for deprecated constant AST.JSL3 |
| * to alleviate deprecation warnings. |
| * @deprecated |
| */ |
| /*package*/ static final int JLS3_INTERNAL = AST.JLS3; |
| |
| static class ReconcileParticipant extends CompilationParticipant { |
| IJavaElementDelta delta; |
| org.eclipse.jdt.core.dom.CompilationUnit ast; |
| ReconcileParticipant() { |
| TestCompilationParticipant.PARTICIPANT = this; |
| } |
| public boolean isActive(IJavaProject project) { |
| return true; |
| } |
| public void reconcile(ReconcileContext context) { |
| this.delta = context.getDelta(); |
| try { |
| this.ast = context.getAST4(); |
| } catch (JavaModelException e) { |
| assertNull("Unexpected exception", e); |
| } |
| } |
| } |
| |
| static class ReconcileParticipant2 extends CompilationParticipant { |
| IJavaElementDelta delta; |
| org.eclipse.jdt.core.dom.CompilationUnit ast; |
| ReconcileParticipant2() { |
| TestCompilationParticipant.PARTICIPANT = this; |
| } |
| public boolean isActive(IJavaProject project) { |
| return true; |
| } |
| public void reconcile(ReconcileContext context) { |
| this.delta = context.getDelta(); |
| try { |
| this.ast = context.getAST4(); |
| assertTrue("Context should have statement recovery enabled", (context.getReconcileFlags() & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0); |
| assertTrue("Context should have ignore method body enabled", (context.getReconcileFlags() & ICompilationUnit.IGNORE_METHOD_BODIES) != 0); |
| } catch (JavaModelException e) { |
| assertNull("Unexpected exception", e); |
| } |
| } |
| } |
| |
| static class ReconcileParticipant3 extends CompilationParticipant { |
| IJavaElementDelta delta; |
| org.eclipse.jdt.core.dom.CompilationUnit ast; |
| ReconcileParticipant3() { |
| TestCompilationParticipant.PARTICIPANT = this; |
| } |
| public boolean isActive(IJavaProject project) { |
| return true; |
| } |
| public void reconcile(ReconcileContext context) { |
| this.delta = context.getDelta(); |
| try { |
| this.ast = context.getAST4(); |
| assertFalse("Context should have statement recovery enabled", (context.getReconcileFlags() & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0); |
| assertTrue("Context should have ignore method body enabled", (context.getReconcileFlags() & ICompilationUnit.IGNORE_METHOD_BODIES) != 0); |
| } catch (JavaModelException e) { |
| assertNull("Unexpected exception", e); |
| } |
| } |
| } |
| /** |
| */ |
| public ReconcilerTests(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[] { "testBug374176" }; |
| // TESTS_NUMBERS = new int[] { 118823 }; |
| // TESTS_RANGE = new int[] { 16, -1 }; |
| } |
| public static Test suite() { |
| return buildModelTestSuite(ReconcilerTests.class); |
| } |
| 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(this.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(); |
| 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(JLS3_INTERNAL, |
| 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.wcOwner = new WorkingCopyOwner() { |
| public IProblemRequestor getProblemRequestor(ICompilationUnit unit) { |
| return ReconcilerTests.this.problemRequestor; |
| } |
| }; |
| this.workingCopy = getCompilationUnit("Reconciler/src/p1/X.java").getWorkingCopy(this.wcOwner, 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_SOURCE, JavaCore.VERSION_1_4); |
| 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); |
| project15.setOption(JavaCore.COMPILER_PB_RAW_TYPE_REFERENCE, JavaCore.IGNORE); |
| } |
| private void setUp15WorkingCopy() throws JavaModelException { |
| setUp15WorkingCopy("Reconciler15/src/p1/X.java", this.wcOwner); |
| } |
| 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, this.wcOwner); |
| } |
| private void setUpWorkingCopy(String path, String contents, WorkingCopyOwner owner) throws JavaModelException { |
| this.workingCopy.discardWorkingCopy(); |
| this.workingCopy = getCompilationUnit(path).getWorkingCopy(owner, null); |
| assertEquals("Invalid problem requestor!", this.problemRequestor, this.wcOwner.getProblemRequestor(this.workingCopy)); |
| 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(); |
| } |
| /* |
| * Ensures that no problem is created for a reference to a type that is included in a prereq project. |
| */ |
| public void testAccessRestriction() throws CoreException { |
| try { |
| createJavaProject("P1", new String[] {"src"}, new String[] {"JCL_LIB"}, null, null, new String[0], null, null, new boolean[0], "bin", null, new String[][] {{"**/X.java"}}, null, "1.4"); |
| createFolder("/P1/src/p"); |
| createFile("/P1/src/p/X.java", "package p; public class X {}"); |
| |
| createJavaProject("P2", new String[] {"src"}, new String[] {"JCL_LIB"}, new String[] {"/P1"}, "bin"); |
| setUpWorkingCopy("/P2/src/Y.java", "public class Y extends p.X {}"); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProject("P1"); |
| deleteProject("P2"); |
| } |
| } |
| /* |
| * Ensures that no problem is created for a reference to a binary type that is included in a prereq project. |
| * (regression test for bug 82542 Internal error during AST creation) |
| */ |
| public void testAccessRestriction2() throws CoreException, IOException { |
| try { |
| IJavaProject project = createJavaProject("P1"); |
| addLibrary( |
| project, |
| "lib.jar", |
| "libsrc.zip", |
| new String[] { |
| "p/X.java", |
| "package p;\n" + |
| "public class X {\n" + |
| "}", |
| }, |
| null/*no non-Java resources*/, |
| new String[] { |
| "**/*" |
| }, |
| null, |
| "1.4", |
| null |
| ); |
| createJavaProject("P2", new String[] {"src"}, new String[] {"JCL_LIB"}, new String[] {"/P1"}, "bin"); |
| setUpWorkingCopy("/P2/src/Y.java", "public class Y extends p.X {}"); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProject("P1"); |
| deleteProject("P2"); |
| } |
| } |
| /* |
| * Ensures that no problem is created for a reference to a type that is included and not exported in a prereq project |
| * but with combineAccessRestriction flag set to false. |
| */ |
| public void testAccessRestriction3() throws CoreException { |
| try { |
| createJavaProject("P1"); |
| createFolder("/P1/p"); |
| createFile("/P1/p/X.java", "package p; public class X {}"); |
| |
| createJavaProject("P2", new String[] {}, new String[] {}, null, null, new String[] {"/P1"}, null, null, new boolean[] {true}, "", null, null, null, "1.4"); |
| |
| createJavaProject("P3", new String[] {"src"}, new String[] {"JCL_LIB"}, null, null, new String[] {"/P2"}, null, new String[][] {new String[] {"**/X"}}, false/*don't combine access restrictions*/, new boolean[] {true}, "bin", null, null, null, "1.4", false/*don't import*/); |
| setUpWorkingCopy("/P3/src/Y.java", "public class Y extends p.X {}"); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProjects(new String[] {"P1", "P2", "P3" }); |
| } |
| } |
| /* |
| * Ensures that a problem is created for a reference to a type that is included and not exported in a prereq project |
| * but with combineAccessRestriction flag set to true. |
| */ |
| public void testAccessRestriction4() throws CoreException { |
| try { |
| createJavaProject("P1"); |
| createFolder("/P1/p"); |
| createFile("/P1/p/X.java", "package p; public class X {}"); |
| |
| createJavaProject("P2", new String[] {}, new String[] {}, null, null, new String[] {"/P1"}, null, null, new boolean[] {true}, "", null, null, null, "1.4"); |
| |
| createJavaProject("P3", new String[] {"src"}, new String[] {"JCL_LIB"}, null, null, new String[] {"/P2"}, null, new String[][] {new String[] {"**/X"}}, true/*combine access restrictions*/, new boolean[] {true}, "bin", null, null, null, "1.4", false/*don't import*/); |
| setUpWorkingCopy("/P3/src/Y.java", "public class Y extends p.X {}"); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /P3/src/Y.java (at line 1)\n" + |
| " public class Y extends p.X {}\n" + |
| " ^^^\n" + |
| "Access restriction: The type X is not accessible due to restriction on required project P1\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProjects(new String[] {"P1", "P2", "P3" }); |
| } |
| } |
| /* |
| * Ensures that a problem is created for a reference to a type that is no longer accessible in a prereq project. |
| * (regression test for bug 91498 Reconcile still sees old access rules) |
| */ |
| public void testAccessRestriction5() throws CoreException { |
| try { |
| createJavaProject("P1"); |
| createFolder("/P1/p"); |
| createFile("/P1/p/X.java", "package p; public class X {}"); |
| IJavaProject p2 = createJavaProject("P2", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| IClasspathEntry[] classpath = p2.getRawClasspath(); |
| int length = classpath.length; |
| System.arraycopy(classpath, 0, classpath = new IClasspathEntry[length+1], 0, length); |
| classpath[length] = createSourceEntry("P2", "/P1", "+**/p/|-**/*"); |
| p2.setRawClasspath(classpath, null); |
| setUpWorkingCopy("/P2/src/Y.java", "public class Y extends p.X {}"); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| |
| // remove accessible rule |
| System.arraycopy(classpath, 0, classpath = new IClasspathEntry[length+1], 0, length); |
| classpath[length] = createSourceEntry("P2", "/P1", "-**/*"); |
| p2.setRawClasspath(classpath, null); |
| this.problemRequestor.initialize(this.workingCopy.getSource().toCharArray()); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /P2/src/Y.java (at line 1)\n" + |
| " public class Y extends p.X {}\n" + |
| " ^^^\n" + |
| "Access restriction: The type X is not accessible due to restriction on required project P1\n" + |
| "----------\n" |
| ); |
| |
| } finally { |
| deleteProjects(new String[] {"P1", "P2"}); |
| } |
| } |
| /** |
| * Ensures that the reconciler handles duplicate members correctly. |
| */ |
| public void testAddDuplicateMember() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()#2[+]: {}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents, updating the structure of this reconciler's compilation |
| * unit, and fires the Java element delta for the structural changes |
| * of the addition of a field and a constructor. |
| */ |
| public void testAddFieldAndConstructor() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " int i;\n" + |
| " X(int i) {\n" + |
| " this.i = i;\n" + |
| " }\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " X(int)[+]: {}\n" + |
| " i[+]: {}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents, updating the structure of this reconciler's compilation |
| * unit, and fires the Java element delta for the structural changes |
| * of the addition of a field and a constructor. |
| */ |
| public void testAddImports() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "import java.lang.reflect.*;\n" + |
| "import java.util.Vector;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "<import container>[*]: {CHILDREN | FINE GRAINED}\n" + |
| " import java.lang.reflect.*[+]: {}\n" + |
| " import java.util.Vector[+]: {}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents, updating the structure of this reconciler's compilation |
| * unit, and fires the Java element delta for the structural changes |
| * of the addition of a method. |
| */ |
| public void testAddMethod1() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| " public void bar() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " bar()[+]: {}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents,updating the structure of this reconciler's compilation |
| * unit, and fires the Java element delta for the structural changes |
| * of the addition of a portion of a new method. |
| */ |
| public void testAddPartialMethod1() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void some()\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " some()[+]: {}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents,updating the structure of this reconciler's compilation |
| * unit, and fires the Java element delta for the structural changes |
| * of the addition of a portion of a new method. Ensures that when a |
| * second part is added to the new method no structural changes are recognized. |
| */ |
| public void testAddPartialMethod1and2() throws JavaModelException { |
| // Add partial method before foo |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void some()\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| |
| // Add { on partial method |
| clearDeltas(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void some() {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "[Working copy] X.java[*]: {CONTENT | FINE GRAINED}" |
| ); |
| } |
| /* |
| * Ensures that the delta is correct when adding an annotation |
| */ |
| public void testAnnotations1() throws JavaModelException { |
| setUp15WorkingCopy(); |
| clearDeltas(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " @MyAnnot\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {ANNOTATIONS}\n" + |
| " @MyAnnot[+]: {}" |
| ); |
| } |
| /* |
| * Ensures that the delta is correct when removing an annotation |
| */ |
| public void testAnnotations2() throws JavaModelException { |
| setUp15WorkingCopy(); |
| clearDeltas(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " @MyAnnot\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.makeConsistent(null); |
| |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {ANNOTATIONS}\n" + |
| " @MyAnnot[-]: {}" |
| ); |
| } |
| /* |
| * Ensures that the delta is correct when changing an annotation |
| */ |
| public void testAnnotations3() throws JavaModelException { |
| setUp15WorkingCopy(); |
| clearDeltas(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " @MyAnnot(x=1)\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.makeConsistent(null); |
| |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " @MyAnnot(y=1)\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {ANNOTATIONS}\n" + |
| " @MyAnnot[*]: {CONTENT}" |
| ); |
| } |
| /* |
| * Ensures that the delta is correct when changing an annotation |
| */ |
| public void testAnnotations4() throws JavaModelException { |
| setUp15WorkingCopy(); |
| clearDeltas(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " @MyAnnot(x=1)\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.makeConsistent(null); |
| |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " @MyAnnot(x=2)\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {ANNOTATIONS}\n" + |
| " @MyAnnot[*]: {CONTENT}" |
| ); |
| } |
| /* |
| * Ensures that no error is reported if an annotation type's cu starts with a slash |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=214450 ) |
| */ |
| public void testAnnotations5() throws JavaModelException { |
| ICompilationUnit annotation = null; |
| try { |
| setUp15WorkingCopy(); |
| annotation = getWorkingCopy( |
| "Reconciler15/src/p1/MyAnnot2.java", |
| "/* test */\n" + |
| "package p1;\n" + |
| "public @interface MyAnnot2 {\n" + |
| " String bar();\n" + |
| "}", |
| this.wcOwner); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " @MyAnnot2(bar=\"a\")\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (annotation != null) |
| annotation.discardWorkingCopy(); |
| } |
| } |
| /* |
| * Ensures that the AST broadcasted during a reconcile operation is correct. |
| * (case of a working copy being reconciled with changes, creating AST and no problem detection) |
| */ |
| public void testBroadcastAST1() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| "}"); |
| this.workingCopy.reconcile(JLS3_INTERNAL, false/*don't force problem detection*/, null/*primary owner*/, null/*no progress*/); |
| assertASTNodeEquals( |
| "Unexpected ast", |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| "}\n", |
| this.deltaListener.getCompilationUnitAST(this.workingCopy)); |
| } |
| /* |
| * Ensures that the AST broadcasted during a reconcile operation is correct. |
| * (case of a working copy being reconciled with NO changes, creating AST and forcing problem detection) |
| */ |
| public void testBroadcastAST2() throws JavaModelException { |
| this.workingCopy.reconcile(JLS3_INTERNAL, true/*force problem detection*/, null/*primary owner*/, null/*no progress*/); |
| assertASTNodeEquals( |
| "Unexpected ast", |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo(){\n" + |
| " }\n" + |
| "}\n", |
| this.deltaListener.getCompilationUnitAST(this.workingCopy)); |
| } |
| /* |
| * Ensures that no AST is broadcasted during a reconcile operation if the working copy being reconciled |
| * has NO changes and NO problem detection is requested) |
| */ |
| public void testBroadcastAST3() throws JavaModelException { |
| this.workingCopy.reconcile(JLS3_INTERNAL, false/*don't force problem detection*/, null/*primary owner*/, null/*no progress*/); |
| assertASTNodeEquals( |
| "Unexpected ast", |
| "null", |
| this.deltaListener.getCompilationUnitAST(this.workingCopy)); |
| } |
| /* |
| * Ensures that the AST broadcasted during a reconcile operation is correct. |
| * (case of a working copy being reconciled twice in a batch operation) |
| */ |
| public void testBroadcastAST4() throws CoreException { |
| JavaCore.run( |
| new IWorkspaceRunnable() { |
| public void run(IProgressMonitor monitor) throws CoreException { |
| ReconcilerTests.this.workingCopy.reconcile(JLS3_INTERNAL, true/*force problem detection*/, null/*primary owner*/, monitor); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| "}"); |
| ReconcilerTests.this.workingCopy.reconcile(JLS3_INTERNAL, false/*don't force problem detection*/, null/*primary owner*/, monitor); |
| } |
| }, |
| null/*no progress*/); |
| assertASTNodeEquals( |
| "Unexpected ast", |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| "}\n", |
| this.deltaListener.getCompilationUnitAST(this.workingCopy)); |
| } |
| /* |
| * Ensures that the AST broadcasted doesn't have a type root that is caching its contents |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=222213 ) |
| */ |
| public void testBroadcastAST5() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| "}"); |
| this.workingCopy.reconcile(JLS3_INTERNAL, false/*don't force problem detection*/, null/*primary owner*/, null/*no progress*/); |
| org.eclipse.jdt.core.dom.CompilationUnit compilationUnit = this.deltaListener.getCompilationUnitAST(this.workingCopy); |
| String newContents = |
| "package p1;\n" + |
| "public class X {\n" + |
| "}"; |
| setWorkingCopyContents(newContents); |
| org.eclipse.jdt.internal.compiler.env.ICompilationUnit compilerCU = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) compilationUnit.getTypeRoot(); |
| assertSourceEquals("Unexpected contents", newContents, new String(compilerCU.getContents())); |
| } |
| /* |
| * Ensures that reconciling a subclass doesn't close the buffer while resolving its superclass. |
| * (regression test for bug 62854 refactoring does not trigger reconcile) |
| */ |
| public void testBufferOpenAfterReconcile() throws CoreException { |
| try { |
| createFile( |
| "/Reconciler/src/p1/Super.java", |
| "package p1;\n" + |
| "public class Super {\n" + |
| "}" |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X extends Super {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}"); |
| IBuffer buffer = this.workingCopy.getBuffer(); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null); |
| assertTrue("Buffer should still be open", !buffer.isClosed()); |
| } finally { |
| 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 |
| */ |
| public void testCancel() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " void foo(String s) {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.makeConsistent(null); |
| |
| // count the number of time isCanceled() is called when converting this source unit |
| CancelCounter counter = new CancelCounter(); |
| this.workingCopy.reconcile(AST.JLS2, true, null, counter); |
| |
| // throw an OperatonCanceledException at each point isCanceled() is called |
| for (int i = 0; i < counter.count; i++) { |
| boolean gotException = false; |
| try { |
| this.workingCopy.reconcile(AST.JLS2, true, null, new Canceler(i)); |
| } catch (OperationCanceledException e) { |
| gotException = true; |
| } |
| assertTrue("Should get an OperationCanceledException (" + i + ")", gotException); |
| } |
| |
| // last should not throw an OperationCanceledException |
| this.workingCopy.reconcile(AST.JLS2, true, null, new Canceler(counter.count)); |
| } |
| /** |
| * Ensures that the delta is correct when adding a category |
| */ |
| public void testCategories1() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " /**\n" + |
| " * @category cat1\n" + |
| " */\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {CATEGORIES}" |
| ); |
| } |
| /** |
| * Ensures that the delta is correct when removing a category |
| */ |
| public void testCategories2() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " /**\n" + |
| " * @category cat1\n" + |
| " */\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.makeConsistent(null); |
| |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {CATEGORIES}" |
| ); |
| } |
| /** |
| * Ensures that the delta is correct when changing a category |
| */ |
| public void testCategories3() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " /**\n" + |
| " * @category cat1\n" + |
| " */\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.makeConsistent(null); |
| |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " /**\n" + |
| " * @category cat2\n" + |
| " */\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {CATEGORIES}" |
| ); |
| } |
| /* |
| * Ensures that the delta is correct when adding a category to a second field |
| * (regression test for bug 125675 @category not reflected in outliner in live fashion) |
| */ |
| public void testCategories4() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " /**\n" + |
| " * @category cat1\n" + |
| " */\n" + |
| " int f1;\n" + |
| " int f2;\n" + |
| "}" |
| ); |
| this.workingCopy.makeConsistent(null); |
| |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " /**\n" + |
| " * @category cat1\n" + |
| " */\n" + |
| " int f1;\n" + |
| " /**\n" + |
| " * @category cat2\n" + |
| " */\n" + |
| " int f2;\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " f2[*]: {CATEGORIES}" |
| ); |
| } |
| /* |
| * Ensures that changing the source level to make a type valid doesn't report an error any longer |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=233568 ) |
| */ |
| public void testChangeSourceLevel1() throws Exception { |
| try { |
| IJavaProject p = createJavaProject("P1", new String[] {"src"}, new String[] {"JCL15_LIB", "/P1/lib.jar"}, "bin", "1.5"); |
| Util.createJar(new String[] { |
| "p/enum/X.java", |
| "package p.enum;\n" + |
| "public class X{\n" + |
| "}" |
| }, |
| p.getProject().getLocation().append("lib.jar").toOSString(), |
| "1.3"); |
| refresh(p); |
| setUpWorkingCopy( |
| "/P1/src/p1/X.java", |
| "package p1;\n" + |
| "public class X {\n" + |
| " p.enum.X field;\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| /* At this point, the following error is reported: |
| "----------\n" + |
| "1. ERROR in /P1/src/p1/X.java (at line 3)\n" + |
| " p.enum.X field;\n" + |
| " ^^^^\n" + |
| "Syntax error on token \"enum\", Identifier expected\n" + |
| "----------\n" |
| */ |
| |
| this.problemRequestor.reset(); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /P1/src/p1/X.java (at line 3)\n" + |
| " p.enum.X field;\n" + |
| " ^^^^\n" + |
| "\'enum\' should not be used as an identifier, since it is a reserved keyword from source level 1.5 on\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProject("P1"); |
| } |
| } |
| /* |
| * Ensures that changing the source level to make a type valid doesn't report an error any longer |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=233568 ) |
| */ |
| public void testChangeSourceLevel2() throws Exception { |
| Hashtable defaultOptions = null; |
| try { |
| defaultOptions = JavaCore.getOptions(); |
| Hashtable newOptions = new Hashtable(); |
| newOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| JavaCore.setOptions(newOptions); |
| IJavaProject p = createJavaProject("P1", new String[] {"src"}, new String[] {"JCL15_LIB", "/P1/lib.jar"}, "bin"); |
| Util.createJar(new String[] { |
| "p/enum/X.java", |
| "package p.enum;\n" + |
| "public class X{\n" + |
| "}" |
| }, |
| p.getProject().getLocation().append("lib.jar").toOSString(), |
| "1.3"); |
| refresh(p); |
| setUpWorkingCopy( |
| "/P1/src/p1/X.java", |
| "package p1;\n" + |
| "public class X {\n" + |
| " p.enum.X field;\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| /* At this point, the following error is reported: |
| "----------\n" + |
| "1. ERROR in /P1/src/p1/X.java (at line 3)\n" + |
| " p.enum.X field;\n" + |
| " ^^^^\n" + |
| "Syntax error on token \"enum\", Identifier expected\n" + |
| "----------\n" |
| */ |
| |
| this.problemRequestor.reset(); |
| newOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3); |
| JavaCore.setOptions(newOptions); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /P1/src/p1/X.java (at line 3)\n" + |
| " p.enum.X field;\n" + |
| " ^^^^\n" + |
| "\'enum\' should not be used as an identifier, since it is a reserved keyword from source level 1.5 on\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProject("P1"); |
| if (defaultOptions != null) |
| JavaCore.setOptions(defaultOptions); |
| } |
| } |
| /* |
| * Ensures that changing a binary folder used as class folder in 2 projects doesn't cause the old binary to be seen |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=210746 ) |
| */ |
| public void testChangeClassFolder() throws CoreException { |
| try { |
| createJavaProject("P1", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| createFolder("/P1/src/p"); |
| createFile( |
| "/P1/src/p/X.java", |
| "package p;\n" + |
| "public class X {\n" + |
| "}" |
| ); |
| getProject("P1").build(IncrementalProjectBuilder.FULL_BUILD, null); |
| createJavaProject("P2", new String[0], new String[] {"/P1/bin"}, "bin"); |
| createJavaProject("P3", new String[] {"src"}, new String[] {"JCL_LIB", "/P1/bin"}, "bin"); |
| setUpWorkingCopy( |
| "/P3/src/q/Y.java", |
| "package q;\n" + |
| "import p.X;\n" + |
| "public class Y {\n" + |
| " void foo(X x) {\n" + |
| " }\n"+ |
| "}" |
| ); |
| editFile( |
| "/P1/src/p/X.java", |
| "package p;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " }\n" + |
| "}" |
| ); |
| getProject("P1").build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| setWorkingCopyContents( |
| "package q;\n" + |
| "import p.X;\n" + |
| "public class Y {\n" + |
| " void foo(X x) {\n" + |
| " x.bar();\n" + |
| " }\n"+ |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProjects(new String[] {"P1", "P2", "P3"}); |
| } |
| } |
| /* |
| * Ensures that changing and external jar and refreshing takes the change into account |
| * (regression test for bug 134110 [regression] Does not pick-up interface changes from classes in the build path) |
| */ |
| public void testChangeExternalJar() throws CoreException, IOException { |
| IJavaProject project = getJavaProject("Reconciler"); |
| String jarPath = getExternalPath() + "lib.jar"; |
| try { |
| createJar(new String[] { |
| "p/Y.java", |
| "package p;\n" + |
| "public class Y {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}" |
| }, jarPath); |
| addLibraryEntry(project, jarPath, false); |
| |
| // force Y.class file to be cached during resolution |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X extends p.Y {\n" + |
| " public void bar() {\n" + |
| " foo();\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| |
| // change jar and refresh |
| createJar(new String[] { |
| "p/Y.java", |
| "package p;\n" + |
| "public class Y {\n" + |
| " public void foo(String s) {\n" + |
| " }\n" + |
| "}" |
| }, jarPath); |
| getJavaModel().refreshExternalArchives(null,null); |
| |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X extends p.Y {\n" + |
| " public void bar() {\n" + |
| " foo(\"a\");\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| removeClasspathEntry(project, new Path(jarPath)); |
| deleteResource(new File(jarPath)); |
| } |
| } |
| /** |
| * @bug 162621: [model][delta] Validation errors do not clear after replacing jar file |
| * @test Ensures that changing an internal jar and refreshing takes the change into account |
| * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=162621" |
| */ |
| public void testChangeInternalJar() throws CoreException, IOException { |
| IJavaProject project = getJavaProject("Reconciler"); |
| String jarName = "b162621.jar"; |
| try { |
| String[] pathAndContents = new String[] { |
| "test/before/Foo.java", |
| "package test.before;\n" + |
| "public class Foo {\n" + |
| "}\n" |
| }; |
| addLibrary(project, jarName, "b162621_src.zip", pathAndContents, JavaCore.VERSION_1_4); |
| |
| // Wait a little bit to be sure file system is aware of zip file creation |
| try { |
| Thread.sleep(1000); |
| } |
| catch (InterruptedException ie) { |
| // skip |
| } |
| |
| // Set working copy content with no error |
| setUpWorkingCopy("/Reconciler/src/test/Test.java", |
| "package test;\n" + |
| "import test.before.Foo;\n" + |
| "public class Test {\n" + |
| " Foo f;\n" + |
| "}\n" |
| ); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| |
| // Update working copy with Jar expected changes |
| String contents = "package test;\n" + |
| "import test.after.Foo;\n" + |
| "public class Test {\n" + |
| " Foo f;\n" + |
| "}\n"; |
| setWorkingCopyContents(contents); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null); |
| assertProblems( |
| "Wrong expected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/test/Test.java (at line 2)\n" + |
| " import test.after.Foo;\n" + |
| " ^^^^^^^^^^\n" + |
| "The import test.after cannot be resolved\n" + |
| "----------\n" + |
| "2. ERROR in /Reconciler/src/test/Test.java (at line 4)\n" + |
| " Foo f;\n" + |
| " ^^^\n" + |
| "Foo cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| |
| // change jar and refresh |
| String projectLocation = project.getProject().getLocation().toOSString(); |
| String jarPath = projectLocation + File.separator + jarName; |
| createJar(new String[] { |
| "test/after/Foo.java", |
| "package test.after;\n" + |
| "public class Foo {\n" + |
| "}\n" |
| }, jarPath); |
| project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null); |
| |
| try { |
| Thread.sleep(1000); |
| } |
| catch (InterruptedException ie) { |
| // skip |
| } |
| |
| // Verify that error is gone |
| this.problemRequestor.initialize(contents.toCharArray()); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| removeClasspathEntry(project, new Path(jarName)); |
| deleteResource(new File(jarName)); |
| } |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents,updating the structure of this reconciler's compilation |
| * unit, and fires the Java element deltas for the structural changes |
| * of a method's type parameter change. |
| */ |
| public void testChangeMethodTypeParameters() throws JavaModelException { |
| setUp15WorkingCopy(); |
| clearDeltas(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public <T> void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {CONTENT}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents,updating the structure of this reconciler's compilation |
| * unit, and fires the Java element deltas for the structural changes |
| * of a type's type parameter change. |
| */ |
| public void testChangeTypeTypeParameters() throws JavaModelException { |
| setUp15WorkingCopy(); |
| clearDeltas(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X <T> {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CONTENT}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents,updating the structure of this reconciler's compilation |
| * unit, and fires the Java element deltas for the structural changes |
| * of a method visibility change. |
| */ |
| public void testChangeMethodVisibility() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " private void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {MODIFIERS CHANGED}" |
| ); |
| } |
| /** |
| * Ensures that the correct delta is reported when closing the working copy and modifying its buffer. |
| */ |
| public void testCloseWorkingCopy() throws JavaModelException { |
| IBuffer buffer = this.workingCopy.getBuffer(); |
| this.workingCopy.close(); |
| buffer.setContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| " public void bar() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " bar()[+]: {}" |
| ); |
| } |
| |
| /** |
| * Ensures that a reference to a constant with type mismatch doesn't show an error. |
| * (regression test for bug 17104 Compiler does not complain but "Quick Fix" ??? complains) |
| */ |
| public void testConstantReference() throws CoreException { |
| try { |
| createFile( |
| "/Reconciler/src/p1/OS.java", |
| "package p1;\n" + |
| "public class OS {\n" + |
| " public static final int CONST = 23 * 1024;\n" + |
| "}"); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " public short c;\n" + |
| " public static void main(String[] arguments) {\n" + |
| " short c = 1;\n" + |
| " switch (c) {\n" + |
| " case OS.CONST: return;\n" + |
| " }\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteFile("/Reconciler/src/p1/OS.java"); |
| } |
| } |
| /* |
| * Ensures that the source type converter doesn't throw an OutOfMemoryError if converting a generic type with a primitive type array as argument |
| * (regression test for bug 135296 opening a special java file results in an "out of memory" message) |
| */ |
| public void testConvertPrimitiveTypeArrayTypeArgument() throws CoreException { |
| ICompilationUnit otherCopy = null; |
| try { |
| otherCopy = getWorkingCopy( |
| "Reconciler15/src/Y.java", |
| "public class Y {\n" + |
| " void foo(Z<int[]> z) {}\n" + |
| "}\n" + |
| "class Z<E> {\n" + |
| "}", |
| this.wcOwner |
| ); |
| setUp15WorkingCopy("/Reconciler15/src/X.java", this.wcOwner); |
| setWorkingCopyContents( |
| "public class X {\n" + |
| " void bar(Y y) {\n" + |
| " y.foo(new Z<int[]>());\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (otherCopy != null) |
| otherCopy.discardWorkingCopy(); |
| } |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents, updating the structure of this reconciler's compilation |
| * unit, and fires the Java element deltas for the structural changes |
| * of a method being deleted. |
| */ |
| public void testDeleteMethod1() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[-]: {}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents, updating the structure of this reconciler's compilation |
| * unit, and fires the Java element deltas for the structural changes |
| * of two methods being deleted. |
| */ |
| public void testDeleteTwoMethods() throws JavaModelException { |
| // create 2 methods |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| " public void bar() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| |
| // delete the 2 methods |
| clearDeltas(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " bar()[-]: {}\n" + |
| " foo()[-]: {}" |
| ); |
| } |
| /* |
| * Ensures that excluded part of prereq project are not visible |
| */ |
| public void testExcludePartOfAnotherProject1() throws CoreException { |
| IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P", "-**/internal/"}); |
| try { |
| addClasspathEntries(newEntries, true); |
| createJavaProject("P"); |
| createFolder("/P/p/internal"); |
| createFile( |
| "/P/p/internal/Y.java", |
| "package p.internal;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X extends p.internal.Y {\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/X.java (at line 2)\n" + |
| " public class X extends p.internal.Y {\n" + |
| " ^^^^^^^^^^^^\n" + |
| "Access restriction: The type Y is not accessible due to restriction on required project P\n" + |
| "----------\n" |
| ); |
| } finally { |
| removeClasspathEntries(newEntries); |
| deleteProject("P"); |
| } |
| } |
| /* |
| * Ensures that packages that are not in excluded part of prereq project are visible |
| */ |
| public void testExcludePartOfAnotherProject2() throws CoreException { |
| IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P", "-**/internal/"}); |
| try { |
| addClasspathEntries(newEntries, true); |
| createJavaProject("P"); |
| createFolder("/P/p/api"); |
| createFile( |
| "/P/p/api/Y.java", |
| "package p.api;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X extends p.api.Y {\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| removeClasspathEntries(newEntries); |
| deleteProject("P"); |
| } |
| } |
| /* |
| * Ensures that an external working copy can be reconciled with no error. |
| */ |
| public void testExternal1() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| this.problemRequestor = new ProblemRequestor(); |
| IClasspathEntry[] classpath = new IClasspathEntry[] {JavaCore.newLibraryEntry(getExternalJCLPath(), null, null)}; |
| this.workingCopy = newExternalWorkingCopy("External.java", classpath, this.problemRequestor, |
| "public class External {\n"+ |
| " String foo(){\n"+ |
| " return \"\";\n" + |
| " }\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null/*no owner*/, null); |
| |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } |
| |
| /* |
| * Ensures that an external working copy with a container classpath entry can be reconciled with no exception. |
| * (regression test for bug 148970 Exceptions opening external Java file) |
| */ |
| public void testExternal2() throws CoreException { |
| class LogListener implements ILogListener { |
| IStatus loggedStatus; |
| public void logging(IStatus status, String plugin) { |
| this.loggedStatus = status; |
| } |
| } |
| LogListener listener = new LogListener(); |
| try { |
| Platform.addLogListener(listener); |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| this.problemRequestor = new ProblemRequestor(); |
| ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {" ", getExternalJCLPathString()})); |
| IClasspathEntry[] classpath = new IClasspathEntry[] { |
| JavaCore.newContainerEntry(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER")) |
| }; |
| this.workingCopy = newExternalWorkingCopy("External.java", classpath, this.problemRequestor, |
| "public class External {\n"+ |
| " String foo(){\n"+ |
| " return \"\";\n" + |
| " }\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null/*no owner*/, null); |
| assertEquals("Should not get any exception in log", null, listener.loggedStatus); |
| } finally { |
| Platform.removeLogListener(listener); |
| } |
| } |
| |
| /* |
| * Ensures that an error is detected after refreshing external archives used by |
| * an external working copy. |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=216772 ) |
| */ |
| public void testExternal3() throws Exception { |
| try { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| this.problemRequestor = new ProblemRequestor(); |
| createJar(new String[] { |
| "p/Lib.java", |
| "package p;\n" + |
| "public class Lib {\n" + |
| "}" |
| }, getExternalResourcePath("lib.jar")); |
| IClasspathEntry[] classpath = new IClasspathEntry[] { |
| JavaCore.newLibraryEntry(getExternalJCLPath(), null, null), |
| JavaCore.newLibraryEntry(new Path(getExternalResourcePath("lib.jar")), null, null) |
| }; |
| this.workingCopy = newExternalWorkingCopy("External.java", classpath, this.problemRequestor, |
| "public class External {\n"+ |
| " p.Lib field;\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null/*no owner*/, null); |
| |
| createJar(new String[] { |
| "p/Lib2.java", |
| "package p;\n" + |
| "public class Lib2 {\n" + |
| "}" |
| }, getExternalResourcePath("lib.jar")); |
| getJavaModel().refreshExternalArchives(null, null); |
| this.problemRequestor.reset(); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null/*no owner*/, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in / /External.java\n" + |
| "p.Lib cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteExternalResource("lib.jar"); |
| } |
| } |
| |
| /* |
| * Ensures that included part of prereq project are visible |
| */ |
| public void testIncludePartOfAnotherProject1() throws CoreException { |
| IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P", "+**/api/"}); |
| try { |
| addClasspathEntries(newEntries, true); |
| createJavaProject("P"); |
| createFolder("/P/p/api"); |
| createFile( |
| "/P/p/api/Y.java", |
| "package p.api;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X extends p.api.Y {\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| removeClasspathEntries(newEntries); |
| deleteProject("P"); |
| } |
| } |
| /* |
| * Ensures that packages that are not in included part of prereq project are not visible |
| */ |
| public void testIncludePartOfAnotherProject2() throws CoreException { |
| IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P", "+**/api/|-**"}); |
| try { |
| addClasspathEntries(newEntries, true); |
| createJavaProject("P"); |
| createFolder("/P/p/internal"); |
| createFile( |
| "/P/p/internal/Y.java", |
| "package p.internal;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X extends p.internal.Y {\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/X.java (at line 2)\n" + |
| " public class X extends p.internal.Y {\n" + |
| " ^^^^^^^^^^^^\n" + |
| "Access restriction: The type Y is not accessible due to restriction on required project P\n" + |
| "----------\n" |
| ); |
| } finally { |
| removeClasspathEntries(newEntries); |
| deleteProject("P"); |
| } |
| } |
| /** |
| * Start with no imports, add an import, and then append to the import name. |
| */ |
| public void testGrowImports() throws JavaModelException { |
| // no imports |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| |
| // add an import |
| clearDeltas(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p\n" + |
| "public class X {\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "<import container>[+]: {}" |
| ); |
| |
| // append to import name |
| clearDeltas(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2\n" + |
| "public class X {\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "<import container>[*]: {CHILDREN | FINE GRAINED}\n" + |
| " import p2[+]: {}\n" + |
| " import p[-]: {}" |
| ); |
| } |
| /* |
| * Ensures that a type matching a ignore-if-better non-accessible rule is further found when accessible |
| * on another classpath entry. |
| * (regression test for bug 98127 Access restrictions started showing up after switching to bundle) |
| */ |
| public void testIgnoreIfBetterNonAccessibleRule1() throws CoreException { |
| IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P1", "?**/internal/", "/P2", "+**/internal/Y"}); |
| try { |
| addClasspathEntries(newEntries, true); |
| createJavaProject("P1"); |
| createFolder("/P1/p/internal"); |
| createFile( |
| "/P1/p/internal/Y.java", |
| "package p.internal;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| createJavaProject("P2"); |
| createFolder("/P2/p/internal"); |
| createFile( |
| "/P2/p/internal/Y.java", |
| "package p.internal;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X extends p.internal.Y {\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| removeClasspathEntries(newEntries); |
| deleteProjects(new String[] {"P1", "P2"}); |
| } |
| } |
| /* |
| * Ensures that a type matching a ignore-if-better non-accessible rule is further found when accessible |
| * on another classpath entry. |
| * (regression test for bug 98127 Access restrictions started showing up after switching to bundle) |
| */ |
| public void testIgnoreIfBetterNonAccessibleRule2() throws CoreException { |
| IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P1", "?**/internal/", "/P2", "~**/internal/Y"}); |
| try { |
| addClasspathEntries(newEntries, true); |
| createJavaProject("P1"); |
| createFolder("/P1/p/internal"); |
| createFile( |
| "/P1/p/internal/Y.java", |
| "package p.internal;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| createJavaProject("P2"); |
| createFolder("/P2/p/internal"); |
| createFile( |
| "/P2/p/internal/Y.java", |
| "package p.internal;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X extends p.internal.Y {\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler/src/p1/X.java (at line 2)\n" + |
| " public class X extends p.internal.Y {\n" + |
| " ^^^^^^^^^^^^\n" + |
| "Discouraged access: The type Y is not accessible due to restriction on required project P2\n" + |
| "----------\n" |
| ); |
| } finally { |
| removeClasspathEntries(newEntries); |
| deleteProjects(new String[] {"P1", "P2"}); |
| } |
| } |
| /* |
| * Ensures that a type matching a ignore-if-better non-accessible rule is further found non-accessible |
| * on another classpath entry. |
| * (regression test for bug 98127 Access restrictions started showing up after switching to bundle) |
| */ |
| public void testIgnoreIfBetterNonAccessibleRule3() throws CoreException { |
| IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P1", "?**/internal/", "/P2", "-**/internal/Y"}); |
| try { |
| addClasspathEntries(newEntries, true); |
| createJavaProject("P1"); |
| createFolder("/P1/p/internal"); |
| createFile( |
| "/P1/p/internal/Y.java", |
| "package p.internal;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| createJavaProject("P2"); |
| createFolder("/P2/p/internal"); |
| createFile( |
| "/P2/p/internal/Y.java", |
| "package p.internal;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X extends p.internal.Y {\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/X.java (at line 2)\n" + |
| " public class X extends p.internal.Y {\n" + |
| " ^^^^^^^^^^^^\n" + |
| "Access restriction: The type Y is not accessible due to restriction on required project P1\n" + |
| "----------\n" |
| ); |
| } finally { |
| removeClasspathEntries(newEntries); |
| deleteProjects(new String[] {"P1", "P2"}); |
| } |
| } |
| /* |
| * Ensures that a type matching a ignore-if-better non-accessible rule is found non-accessible |
| * if no other classpath entry matches it. |
| * (regression test for bug 98127 Access restrictions started showing up after switching to bundle) |
| */ |
| public void testIgnoreIfBetterNonAccessibleRule4() throws CoreException { |
| IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P1", "?**/internal/"}); |
| try { |
| addClasspathEntries(newEntries, true); |
| createJavaProject("P1"); |
| createFolder("/P1/p/internal"); |
| createFile( |
| "/P1/p/internal/Y.java", |
| "package p.internal;\n" + |
| "public class Y {\n" + |
| "}" |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X extends p.internal.Y {\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/X.java (at line 2)\n" + |
| " public class X extends p.internal.Y {\n" + |
| " ^^^^^^^^^^^^\n" + |
| "Access restriction: The type Y is not accessible due to restriction on required project P1\n" + |
| "----------\n" |
| ); |
| } finally { |
| removeClasspathEntries(newEntries); |
| deleteProjects(new String[] {"P1"}); |
| } |
| } |
| /** |
| * Introduces a syntax error in the modifiers of a method. |
| */ |
| public void testMethodWithError01() throws CoreException { |
| // Introduce syntax error |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public.void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta after syntax error", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {MODIFIERS CHANGED}" |
| ); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" + |
| " public.void foo() {\n" + |
| " ^\n" + |
| "Syntax error on token \".\", delete this token\n" + |
| "----------\n" |
| ); |
| |
| // Fix the syntax error |
| clearDeltas(); |
| String contents = |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}"; |
| setWorkingCopyContents(contents); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta after fixing syntax error", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {MODIFIERS CHANGED}" |
| ); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler/src/p1/X.java (at line 2)\n" + |
| " import p2.*;\n" + |
| " ^^\n" + |
| "The import p2 is never used\n" + |
| "----------\n" |
| ); |
| } |
| /** |
| * Test reconcile force flag |
| */ |
| public void testMethodWithError02() throws CoreException { |
| String contents = |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public.void foo() {\n" + |
| " }\n" + |
| "}"; |
| setWorkingCopyContents(contents); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| |
| // use force flag to refresh problems |
| this.problemRequestor.initialize(contents.toCharArray()); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" + |
| " public.void foo() {\n" + |
| " ^\n" + |
| "Syntax error on token \".\", delete this token\n" + |
| "----------\n" |
| ); |
| } |
| |
| /** |
| * Test reconcile force flag off |
| */ |
| public void testMethodWithError03() throws CoreException { |
| String contents = |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public.void foo() {\n" + |
| " }\n" + |
| "}"; |
| setWorkingCopyContents(contents); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| |
| // reconcile with force flag turned off |
| this.problemRequestor.initialize(contents.toCharArray()); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "" |
| ); |
| } |
| /** |
| * Test reconcile force flag + cancel |
| */ |
| public void testMethodWithError04() throws CoreException { |
| |
| CancelingProblemRequestor myPbRequestor = new CancelingProblemRequestor(); |
| |
| this.workingCopy.discardWorkingCopy(); |
| ICompilationUnit x = getCompilationUnit("Reconciler", "src", "p1", "X.java"); |
| this.problemRequestor = myPbRequestor; |
| this.workingCopy = x.getWorkingCopy(this.wcOwner, null); |
| |
| String contents = |
| "package p1;\n" + |
| "public class X {\n" + |
| " Zork f; \n"+ |
| " void foo(Zork z){\n"+ |
| " }\n"+ |
| "} \n"; |
| setWorkingCopyContents(contents); |
| |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| |
| // use force flag to refresh problems |
| myPbRequestor.isCanceling = true; |
| myPbRequestor.initialize(contents.toCharArray()); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, myPbRequestor.progressMonitor); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/X.java (at line 3)\n" + |
| " Zork f; \n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| } |
| |
| /** |
| * Test reconcile force flag off |
| */ |
| public void testMethodWithError05() throws CoreException { |
| try { |
| createFolder("/Reconciler/src/tests"); |
| String contents = |
| "package tests; \n"+ |
| "abstract class AbstractSearchableSource extends AbstractSource implements SearchableSource { \n"+ |
| " abstract int indexOfImpl(long value); \n"+ |
| " public final int indexOf(long value) { \n"+ |
| " return indexOfImpl(value); \n"+ |
| " } \n"+ |
| "} \n"; |
| createFile( |
| "/Reconciler/src/tests/AbstractSearchableSource.java", |
| contents); |
| |
| createFile( |
| "/Reconciler/src/tests/Source.java", |
| "package tests; \n"+ |
| "interface Source { \n"+ |
| " long getValue(int index); \n"+ |
| " int size(); \n"+ |
| "} \n"); |
| |
| createFile( |
| "/Reconciler/src/tests/AbstractSource.java", |
| "package tests; \n"+ |
| "abstract class AbstractSource implements Source { \n"+ |
| " AbstractSource() { \n"+ |
| " } \n"+ |
| " void invalidate() { \n"+ |
| " } \n"+ |
| " abstract long getValueImpl(int index); \n"+ |
| " abstract int sizeImpl(); \n"+ |
| " public final long getValue(int index) { \n"+ |
| " return 0; \n"+ |
| " } \n"+ |
| " public final int size() { \n"+ |
| " return 0; \n"+ |
| " } \n"+ |
| "} \n"); |
| |
| createFile( |
| "/Reconciler/src/tests/SearchableSource.java", |
| "package tests; \n"+ |
| "interface SearchableSource extends Source { \n"+ |
| " int indexOf(long value); \n"+ |
| "} \n"); |
| |
| ICompilationUnit compilationUnit = getCompilationUnit("Reconciler", "src", "tests", "AbstractSearchableSource.java"); |
| ProblemRequestor pbReq = new ProblemRequestor(); |
| WorkingCopyOwner owner = newWorkingCopyOwner(pbReq); |
| ICompilationUnit wc = compilationUnit.getWorkingCopy(owner, null); |
| pbReq.initialize(contents.toCharArray()); |
| startDeltas(); |
| wc.reconcile(ICompilationUnit.NO_AST, true, null, null); |
| String actual = pbReq.problems.toString(); |
| String expected = |
| "----------\n" + |
| "----------\n"; |
| if (!expected.equals(actual)){ |
| System.out.println(Util.displayString(actual, 2)); |
| } |
| assertEquals( |
| "unexpected errors", |
| expected, |
| actual); |
| } finally { |
| deleteFile("/Reconciler/src/tests/AbstractSearchableSource.java"); |
| deleteFile("/Reconciler/src/tests/SearchableSource.java"); |
| deleteFile("/Reconciler/src/tests/Source.java"); |
| deleteFile("/Reconciler/src/tests/AbstractSource.java"); |
| deleteFolder("/Reconciler/src/tests"); |
| } |
| } |
| /* |
| * Test that the creation of a working copy detects errors |
| * (regression test for bug 33757 Problem not detected when opening a working copy) |
| */ |
| public void testMethodWithError06() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| try { |
| String contents = |
| "package p1;\n" + |
| "public class Y {\n" + |
| " public.void foo() {\n" + |
| " }\n" + |
| "}"; |
| createFile( |
| "/Reconciler/src/p1/Y.java", |
| contents |
| ); |
| this.problemRequestor = new ProblemRequestor(); |
| this.problemRequestor.initialize(contents.toCharArray()); |
| this.workingCopy = getCompilationUnit("Reconciler/src/p1/Y.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/Y.java (at line 3)\n" + |
| " public.void foo() {\n" + |
| " ^\n" + |
| "Syntax error on token \".\", delete this token\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteFile("/Reconciler/src/p1/Y.java"); |
| } |
| } |
| /* |
| * Test that the opening of a working copy detects errors |
| * (regression test for bug 33757 Problem not detected when opening a working copy) |
| */ |
| public void testMethodWithError07() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| try { |
| String contents = |
| "package p1;\n" + |
| "public class Y {\n" + |
| " public.void foo() {\n" + |
| " }\n" + |
| "}"; |
| createFile( |
| "/Reconciler/src/p1/Y.java", |
| contents |
| ); |
| this.problemRequestor = new ProblemRequestor(); |
| this.problemRequestor.initialize(contents.toCharArray()); |
| this.workingCopy = getCompilationUnit("Reconciler/src/p1/Y.java").getWorkingCopy(this.wcOwner, null); |
| |
| // Close working copy |
| JavaModelManager.getJavaModelManager().removeInfoAndChildren((CompilationUnit)this.workingCopy); // use a back door as working copies cannot be closed |
| |
| // Reopen should detect syntax error |
| this.problemRequestor.initialize(contents.toCharArray()); |
| this.workingCopy.open(null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/Y.java (at line 3)\n" + |
| " public.void foo() {\n" + |
| " ^\n" + |
| "Syntax error on token \".\", delete this token\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteFile("/Reconciler/src/p1/Y.java"); |
| } |
| } |
| /* |
| * Test that the units with similar names aren't presenting each other errors |
| * (regression test for bug 39475) |
| */ |
| public void testMethodWithError08() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| try { |
| createFile( |
| "/Reconciler/src/p1/X01.java", |
| "package p1;\n" + |
| "public abstract class X01 {\n" + |
| " public abstract void bar(); \n"+ |
| " public abstract void foo(Zork z); \n"+ |
| "}" |
| ); |
| String contents = |
| "package p2;\n" + |
| "public class X01 extends p1.X01 {\n" + |
| " public void bar(){} \n"+ |
| "}"; |
| createFile( |
| "/Reconciler/src/p2/X01.java", |
| contents |
| ); |
| this.problemRequestor = new ProblemRequestor(); |
| this.problemRequestor.initialize(contents.toCharArray()); |
| this.workingCopy = getCompilationUnit("Reconciler/src/p2/X01.java").getWorkingCopy(this.wcOwner, null); |
| |
| // Close working copy |
| JavaModelManager.getJavaModelManager().removeInfoAndChildren((CompilationUnit)this.workingCopy); // use a back door as working copies cannot be closed |
| |
| // Reopen should detect syntax error |
| this.problemRequestor.initialize(contents.toCharArray()); |
| this.workingCopy.open(null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p2/X01.java (at line 2)\n" + |
| " public class X01 extends p1.X01 {\n" + |
| " ^^^\n" + |
| "The type X01 must implement the inherited abstract method X01.foo(Zork)\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteFile("/Reconciler/src/p1/X01.java"); |
| deleteFile("/Reconciler/src/p2/X01.java"); |
| } |
| } |
| /* |
| * Scenario of reconciling using a working copy owner |
| */ |
| public void testMethodWithError09() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| ICompilationUnit workingCopy1 = null; |
| try { |
| workingCopy1 = getCompilationUnit("/Reconciler/src/p1/X1.java").getWorkingCopy(this.wcOwner, null); |
| workingCopy1.getBuffer().setContents( |
| "package p1;\n" + |
| "public abstract class X1 {\n" + |
| " public abstract void bar(); \n"+ |
| "}" |
| ); |
| workingCopy1.makeConsistent(null); |
| |
| this.problemRequestor = new ProblemRequestor(); |
| this.workingCopy = getCompilationUnit("Reconciler/src/p/X.java").getWorkingCopy(this.wcOwner, null); |
| setWorkingCopyContents( |
| "package p;\n" + |
| "public class X extends p1.X1 {\n" + |
| " public void bar(){} \n"+ |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" // shouldn't report problem against p.X |
| ); |
| } finally { |
| if (workingCopy1 != null) { |
| workingCopy1.discardWorkingCopy(); |
| } |
| } |
| } |
| /* |
| * Scenario of reconciling using a working copy owner (68557) |
| */ |
| public void testMethodWithError10() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| ICompilationUnit workingCopy1 = null; |
| try { |
| createFolder("/Reconciler15/src/test/cheetah"); |
| workingCopy1 = getCompilationUnit("/Reconciler15/src/test/cheetah/NestedGenerics.java").getWorkingCopy(this.wcOwner, null); |
| workingCopy1.getBuffer().setContents( |
| "package test.cheetah;\n"+ |
| "import java.util.List;\n"+ |
| "import java.util.Stack;\n"+ |
| "public class NestedGenerics {\n"+ |
| " Stack< List<Object>> stack = new Stack< List<Object> >();\n"+ |
| "}\n" |
| ); |
| workingCopy1.makeConsistent(null); |
| |
| this.problemRequestor = new ProblemRequestor(); |
| this.workingCopy = getCompilationUnit("Reconciler15/src/test/cheetah/NestedGenericsTest.java").getWorkingCopy(this.wcOwner, null); |
| setWorkingCopyContents( |
| "package test.cheetah;\n"+ |
| "import java.util.Stack;\n"+ |
| "public class NestedGenericsTest {\n"+ |
| " void test() { \n"+ |
| " Stack s = new NestedGenerics().stack; \n"+ |
| " }\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (workingCopy1 != null) { |
| workingCopy1.discardWorkingCopy(); |
| } |
| deleteFolder("/Reconciler15/src/test"); |
| } |
| } |
| /* |
| * Scenario of reconciling using a working copy owner (68557) |
| */ |
| public void testMethodWithError11() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| ICompilationUnit workingCopy1 = null; |
| try { |
| createFolder("/Reconciler15/src/test/cheetah"); |
| workingCopy1 = getCompilationUnit("/Reconciler15/src/test/cheetah/NestedGenerics.java").getWorkingCopy(this.wcOwner, null); |
| workingCopy1.getBuffer().setContents( |
| "package test.cheetah;\n"+ |
| "import java.util.*;\n"+ |
| "public class NestedGenerics {\n"+ |
| " Map<List<Object>,String> map = null;\n"+ |
| " Stack<List<Object>> stack2 = null;\n"+ |
| " Map<List<Object>,List<Object>> map3 = null;\n"+ |
| "}\n" |
| ); |
| workingCopy1.makeConsistent(null); |
| |
| this.problemRequestor = new ProblemRequestor(); |
| this.workingCopy = getCompilationUnit("Reconciler15/src/test/cheetah/NestedGenericsTest.java").getWorkingCopy(this.wcOwner, null); |
| setWorkingCopyContents( |
| "package test.cheetah;\n"+ |
| "import java.util.*;\n"+ |
| "public class NestedGenericsTest {\n"+ |
| " void test() { \n"+ |
| " Map m = new NestedGenerics().map; \n"+ |
| " Stack s2 = new NestedGenerics().stack2; \n"+ |
| " Map m3 = new NestedGenerics().map3; \n"+ |
| " }\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (workingCopy1 != null) { |
| workingCopy1.discardWorkingCopy(); |
| } |
| deleteFolder("/Reconciler15/src/test"); |
| } |
| } |
| /* |
| * Scenario of reconciling using a working copy owner (68557 variation with wildcards) |
| */ |
| public void testMethodWithError12() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| ICompilationUnit workingCopy1 = null; |
| try { |
| createFolder("/Reconciler15/src/test/cheetah"); |
| workingCopy1 = getCompilationUnit("/Reconciler15/src/test/cheetah/NestedGenerics.java").getWorkingCopy(this.wcOwner, null); |
| workingCopy1.getBuffer().setContents( |
| "package test.cheetah;\n"+ |
| "import java.util.*;\n"+ |
| "public class NestedGenerics {\n"+ |
| " Map<List<?>,? super String> map = null;\n"+ |
| " Stack<List<? extends Object>> stack2 = null;\n"+ |
| " Map<List<Object[]>,List<Object>[]> map3 = null;\n"+ |
| "}\n" |
| ); |
| workingCopy1.makeConsistent(null); |
| |
| this.problemRequestor = new ProblemRequestor(); |
| this.workingCopy = getCompilationUnit("Reconciler15/src/test/cheetah/NestedGenericsTest.java").getWorkingCopy(this.wcOwner, null); |
| setWorkingCopyContents( |
| "package test.cheetah;\n"+ |
| "import java.util.*;\n"+ |
| "public class NestedGenericsTest {\n"+ |
| " void test() { \n"+ |
| " Map m = new NestedGenerics().map; \n"+ |
| " Stack s2 = new NestedGenerics().stack2; \n"+ |
| " Map m3 = new NestedGenerics().map3; \n"+ |
| " }\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (workingCopy1 != null) { |
| workingCopy1.discardWorkingCopy(); |
| } |
| deleteFolder("/Reconciler15/src/test"); |
| } |
| } |
| /* |
| * Scenario of reconciling using a working copy owner (68730) |
| */ |
| public void testMethodWithError13() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| ICompilationUnit workingCopy1 = null; |
| this.problemRequestor = null; |
| try { |
| workingCopy1 = getCompilationUnit("/Reconciler15/src/test/X.java").getWorkingCopy(this.wcOwner, null); |
| createFolder("/Reconciler15/src/test"); |
| workingCopy1.getBuffer().setContents( |
| "package test;\n"+ |
| "public class X <T extends String, U> {\n"+ |
| " <Y1> void bar(Y1[] y) {}\n"+ |
| " void bar2(Y<E3[]>[] ye[]) {}\n"+ |
| " void foo(java.util.Map<Object[],String>.MapEntry<p.K<T>[],? super q.r.V8> m){}\n"+ |
| " Class<? extends Object> getClass0() {}\n"+ |
| " <E extends String> void pair (X<? extends E, U> e, T t){}\n"+ |
| "}\n" |
| ); |
| workingCopy1.makeConsistent(null); |
| |
| this.problemRequestor = new ProblemRequestor(); |
| this.workingCopy = getCompilationUnit("Reconciler15/src/test/Y.java").getWorkingCopy(this.wcOwner, null); |
| setWorkingCopyContents( |
| "package test;\n"+ |
| "public class Y {\n"+ |
| " void foo(){\n"+ |
| " X someX = new X();\n"+ |
| " someX.bar(null);\n"+ |
| " }\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler15/src/test/Y.java (at line 5)\n" + |
| " someX.bar(null);\n" + |
| " ^^^^^^^^^^^^^^^\n" + |
| "Type safety: The method bar(Object[]) belongs to the raw type X. References to generic type X<T,U> should be parameterized\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (workingCopy1 != null) { |
| workingCopy1.discardWorkingCopy(); |
| } |
| deleteFolder("/Reconciler15/src/test"); |
| } |
| } |
| /* |
| * Scenario of reconciling using a working copy owner (66424) |
| */ |
| public void testMethodWithError14() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| ICompilationUnit workingCopy1 = null; |
| try { |
| workingCopy1 = getCompilationUnit("/Reconciler15/src/test/X.java").getWorkingCopy(this.wcOwner, null); |
| createFolder("/Reconciler15/src/test"); |
| workingCopy1.getBuffer().setContents( |
| "package test;\n"+ |
| "public class X <T> {\n"+ |
| " <U> void bar(U u) {}\n"+ |
| "}\n" |
| ); |
| workingCopy1.makeConsistent(null); |
| |
| this.problemRequestor = new ProblemRequestor(); |
| this.workingCopy = getCompilationUnit("Reconciler15/src/test/Y.java").getWorkingCopy(this.wcOwner, null); |
| setWorkingCopyContents( |
| "package test;\n"+ |
| "public class Y {\n"+ |
| " void foo(){\n"+ |
| " X someX = new X();\n"+ |
| " someX.bar();\n"+ |
| " }\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler15/src/test/Y.java (at line 5)\n" + |
| " someX.bar();\n" + |
| " ^^^\n" + |
| "The method bar(Object) in the type X is not applicable for the arguments ()\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (workingCopy1 != null) { |
| workingCopy1.discardWorkingCopy(); |
| } |
| deleteFolder("/Reconciler15/src/test"); |
| } |
| } |
| /** |
| * Ensures that the reconciler handles member move correctly. |
| */ |
| public void testMoveMember() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| " public void bar() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| clearDeltas(); |
| |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " }\n" + |
| " public void foo() {\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " bar()[*]: {REORDERED}\n" + |
| " foo()[*]: {REORDERED}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler does nothing when the source |
| * to reconcile with is the same as the current contents. |
| */ |
| public void testNoChanges1() throws JavaModelException { |
| setWorkingCopyContents(this.workingCopy.getSource()); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "[Working copy] X.java[*]: {CONTENT | FINE GRAINED}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler does nothing when the source |
| * to reconcile with has the same structure as the current contents. |
| */ |
| public void testNoChanges2() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " System.out.println()\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "[Working copy] X.java[*]: {CONTENT | FINE GRAINED}" |
| ); |
| } |
| /* |
| * Ensures that the problem requestor is not called when the source |
| * to reconcile is the same as the current contents, |
| * no ast is requested, no problem is requested and problem requestor is not active. |
| * (regression test for bug 179258 simple reconcile starts problem finder - main thread waiting) |
| * |
| */ |
| public void testNoChanges3() throws JavaModelException { |
| setWorkingCopyContents(this.workingCopy.getSource()); |
| this.problemRequestor.isActive = false; |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems("Unexpected problems", ""); |
| } |
| /* |
| * Ensures that using a non-generic method with no parameter and with a raw receiver type doesn't create a type safety warning |
| * (regression test for bug 105756 [1.5][model] Incorrect warning on using raw types) |
| */ |
| public void testRawUsage() throws CoreException { |
| ICompilationUnit otherCopy = null; |
| try { |
| otherCopy = getWorkingCopy( |
| "Reconciler15/src/Generic105756.java", |
| "public class Generic105756<T> {\n" + |
| " void foo() {}\n" + |
| "}", |
| this.wcOwner |
| ); |
| setUp15WorkingCopy("/Reconciler15/src/X.java", this.wcOwner); |
| setWorkingCopyContents( |
| "public class X {\n" + |
| " void bar(Generic105756 g) {\n" + |
| " g.foo();\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (otherCopy != null) |
| otherCopy.discardWorkingCopy(); |
| } |
| } |
| /* |
| * Ensures that a reconcile participant is notified when a working copy is reconciled. |
| */ |
| public void testReconcileParticipant01() throws CoreException { |
| ReconcileParticipant participant = new ReconcileParticipant(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " System.out.println()\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertDeltas( |
| "Unexpected participant delta", |
| "[Working copy] X.java[*]: {CHILDREN | FINE GRAINED}\n" + |
| " X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " bar()[+]: {}\n" + |
| " foo()[-]: {}", |
| participant.delta |
| ); |
| } |
| /* |
| * Ensures that a reconcile participant is not notified if not participating. |
| */ |
| public void testReconcileParticipant02() throws CoreException { |
| ReconcileParticipant participant = new ReconcileParticipant(){ |
| public boolean isActive(IJavaProject project) { |
| return false; |
| } |
| }; |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " System.out.println()\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertDeltas( |
| "Unexpected participant delta", |
| "<null>", |
| participant.delta |
| ); |
| } |
| /* |
| * Ensures that a reconcile participant is notified with the correct AST. |
| */ |
| public void testReconcileParticipant03() throws CoreException { |
| ReconcileParticipant participant = new ReconcileParticipant(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " System.out.println()\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertASTNodeEquals( |
| "Unexpected participant ast", |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void bar(){\n" + |
| " }\n" + |
| "}\n", |
| participant.ast |
| ); |
| } |
| /* |
| * Ensures that the same AST as the one a reconcile participant requested is reported. |
| */ |
| public void testReconcileParticipant04() throws CoreException { |
| ReconcileParticipant participant = new ReconcileParticipant(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " System.out.println()\n" + |
| " }\n" + |
| "}" |
| ); |
| org.eclipse.jdt.core.dom.CompilationUnit ast = this.workingCopy.reconcile(AST.JLS4, false, null, null); |
| assertSame( |
| "Unexpected participant ast", |
| participant.ast, |
| ast |
| ); |
| } |
| /* |
| * Ensures that a participant can fix an error during reconcile. |
| */ |
| public void testReconcileParticipant05() throws CoreException { |
| new ReconcileParticipant() { |
| public void reconcile(ReconcileContext context) { |
| try { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " }\n" + |
| "}" |
| ); |
| context.resetAST(); |
| } catch (JavaModelException e) { |
| e.printStackTrace(); |
| } |
| } |
| }; |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " toString()\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } |
| /* |
| * Ensures that a participant can introduce an error during reconcile. |
| */ |
| public void testReconcileParticipant06() throws CoreException { |
| new ReconcileParticipant() { |
| public void reconcile(ReconcileContext context) { |
| try { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " toString()\n" + |
| " }\n" + |
| "}" |
| ); |
| context.resetAST(); |
| } catch (JavaModelException e) { |
| e.printStackTrace(); |
| } |
| } |
| }; |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" + |
| " toString()\n" + |
| " ^\n" + |
| "Syntax error, insert \";\" to complete BlockStatements\n" + |
| "----------\n" |
| ); |
| } |
| /* |
| * Ensures that a reconcile participant is NOT notified when a working copy is reconciled |
| * in a project with insufficient source level. |
| * (regression test for bug 125291 Enable conditional loading of APT) |
| */ |
| public void testReconcileParticipant07() throws CoreException { |
| IJavaProject project = this.workingCopy.getJavaProject(); |
| String originalSourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true); |
| try { |
| project.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_1); |
| ReconcileParticipant participant = new ReconcileParticipant(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " System.out.println()\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertDeltas( |
| "Unexpected participant delta", |
| "<null>", |
| participant.delta |
| ); |
| } finally { |
| project.setOption(JavaCore.COMPILER_SOURCE, originalSourceLevel); |
| } |
| } |
| /* |
| * Ensures that a problem reporting session is not started during reconcile if a participant reports an error |
| * and if the working copy is already consistent and the forceProblemDetection flag is false. |
| * (regression test for bug 154170 Printing warnings breaks in-editor quick fixes) |
| */ |
| public void testReconcileParticipant08() throws CoreException { |
| // set working copy contents and ensure it is consistent |
| String contents = |
| "package p1;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " }\n" + |
| "}"; |
| setWorkingCopyContents(contents); |
| this.workingCopy.makeConsistent(null); |
| this.problemRequestor.initialize(contents.toCharArray()); |
| |
| // reconcile with a participant adding a list of problems |
| new ReconcileParticipant() { |
| public void reconcile(ReconcileContext context) { |
| context.putProblems("test.marker", new CategorizedProblem[] {}); |
| } |
| }; |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "" |
| ); |
| } |
| /* |
| * Ensures that a reconcile participant is not notified when a working copy is reconciled |
| * and it was consistent and forcing problem detection is off |
| * (regression test for 177319 Annotation Processing (APT) affects eclipse speed) |
| */ |
| public void testReconcileParticipant09() throws CoreException { |
| this.workingCopy.makeConsistent(null); |
| new ReconcileParticipant() { |
| public void reconcile(ReconcileContext context) { |
| assertTrue("Participant should not be notified of a reconcile", false); |
| } |
| }; |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false/*don't force problem detection*/, null, null); |
| } |
| |
| /* |
| * Ensures that a reconcile participant is notified when a working copy is reconciled |
| * and it was consistent and forcing problem detection is on |
| */ |
| public void testReconcileParticipant10() throws CoreException { |
| this.workingCopy.makeConsistent(null); |
| final boolean[] participantReconciled = new boolean[1]; |
| new ReconcileParticipant() { |
| public void reconcile(ReconcileContext context) { |
| participantReconciled[0] = true; |
| } |
| }; |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); |
| assertTrue( |
| "Participant should have been notified", |
| participantReconciled[0] |
| ); |
| } |
| |
| /* |
| * Ensures that the delta is still correct if a participant resets the ast during reconcile |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=210310) |
| */ |
| public void testReconcileParticipant11() throws CoreException { |
| new ReconcileParticipant() { |
| public void reconcile(ReconcileContext context) { |
| context.resetAST(); |
| } |
| }; |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " private void foo() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(JLS3_INTERNAL, true/*force problem detection*/, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " foo()[*]: {MODIFIERS CHANGED}" |
| ); |
| } |
| |
| /* |
| * Ensures that a misbehaving reconcile participant doesn't interfere with a reconcile operation |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=248680 ) |
| */ |
| public void testReconcileParticipant12() throws CoreException { |
| try { |
| TestCompilationParticipant.failToInstantiate = true; |
| simulateExitRestart(); |
| this.workingCopy = getCompilationUnit("Reconciler/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " System.out.println()\n" + |
| " }\n" + |
| "}" |
| ); |
| startDeltas(); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected participant delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " bar()[+]: {}\n" + |
| " foo()[-]: {}" |
| ); |
| } finally { |
| stopDeltas(); |
| TestCompilationParticipant.failToInstantiate = false; |
| } |
| } |
| |
| /* |
| * Ensures that errors are fixed if renaming the .classpath file causes the missing type to be visible. |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=207890) |
| */ |
| public void testRenameClasspathFile() throws CoreException { |
| ICompilationUnit copy = null; |
| try { |
| createJavaProject("P1"); |
| deleteFile("/P1/.classpath"); |
| createFile( |
| "/P1/.classpath2", |
| "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + |
| "<classpath>\n" + |
| " <classpathentry kind=\"src\" path=\"src1\"/>\n" + |
| " <classpathentry kind=\"var\" path=\"JCL_LIB\"/>\n" + |
| " <classpathentry kind=\"output\" path=\"bin\"/>\n" + |
| "</classpath>" |
| ); |
| createFolder("/P1/src1/p1"); |
| createFile( |
| "/P1/src1/p1/X.java", |
| "package p1;\n" + |
| "public class X {\n" + |
| "}" |
| ); |
| createJavaProject("P2", new String[] {"src"}, new String[] {"JCL_LIB"}, new String[] {"/P1"}, "bin"); |
| createFolder("/P2/src/p2"); |
| copy = getWorkingCopy( |
| "/P2/src/p2/Y.java", |
| "package p2;\n" + |
| "import p1.X;\n" + |
| "public class Y extends X {\n" + |
| "}", |
| true/*compute problems*/ |
| ); |
| moveFile("/P1/.classpath2", "/P1/.classpath"); |
| this.problemRequestor.reset(); |
| copy.reconcile(ICompilationUnit.NO_AST, true/*for pb detection*/, null/*default owner*/, null/*no progress*/); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (copy != null) |
| copy.discardWorkingCopy(); |
| deleteProject("P1"); |
| deleteProject("P2"); |
| } |
| } |
| |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents, updating the structure of this reconciler's compilation |
| * unit, and fires the Java element deltas for the structural changes |
| * of a renaming a method; the original method deleted and the new method added structurally. |
| */ |
| public void testRenameMethod1() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void bar() {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " bar()[+]: {}\n" + |
| " foo()[-]: {}" |
| ); |
| } |
| /** |
| * Ensures that the reconciler reconciles the new contents with the current |
| * contents,updating the structure of this reconciler's compilation |
| * unit, and fires the Java element delta for the structural changes |
| * of the addition of a portion of a new method. |
| */ |
| public void testRenameWithSyntaxError() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void bar( {\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Unexpected delta", |
| "X[*]: {CHILDREN | FINE GRAINED}\n" + |
| " bar()[+]: {}\n" + |
| " foo()[-]: {}" |
| ); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" + |
| " public void bar( {\n" + |
| " ^\n" + |
| "Syntax error, insert \")\" to complete MethodDeclaration\n" + |
| "----------\n" |
| ); |
| } |
| /* |
| * Ensure that warning are suppressed by an @SuppressWarnings annotation. |
| */ |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=95056 |
| public void testSuppressWarnings1() throws JavaModelException { |
| ICompilationUnit otherCopy = null; |
| try { |
| otherCopy = getWorkingCopy( |
| "/Reconciler15/src/X.java", |
| "@Deprecated\n" + |
| "public class X {\n" + |
| " void foo(){}\n" + |
| "}\n", |
| this.wcOwner |
| ); |
| setUp15WorkingCopy("/Reconciler15/src/Y.java", this.wcOwner); |
| setWorkingCopyContents( |
| "public class Y extends X {\n" + |
| " @SuppressWarnings(\"all\")\n" + |
| " void foo(){ super.foo(); }\n" + |
| " Zork z;\n" + |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler15/src/Y.java (at line 1)\n" + |
| " public class Y extends X {\n" + |
| " ^\n" + |
| "The type X is deprecated\n" + |
| "----------\n" + |
| "2. ERROR in /Reconciler15/src/Y.java (at line 4)\n" + |
| " Zork z;\n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n"); |
| } finally { |
| if (otherCopy != null) |
| otherCopy.discardWorkingCopy(); |
| } |
| } |
| /* |
| * Ensure that warning are suppressed by an @SuppressWarning annotation. |
| */ |
| public void testSuppressWarnings2() throws JavaModelException { |
| ICompilationUnit otherCopy = null; |
| try { |
| otherCopy = getWorkingCopy( |
| "/Reconciler15/src/java/util/List.java", |
| "package java.util;\n" + |
| "public interface List<E> {\n" + |
| "}\n", |
| this.wcOwner |
| ); |
| setUp15WorkingCopy("/Reconciler15/src/X.java", this.wcOwner); |
| setWorkingCopyContents( |
| "import java.util.List;\n" + |
| "\n" + |
| "public class X {\n" + |
| " void foo(List list) {\n" + |
| " List<String> ls1 = list;\n" + |
| " }\n" + |
| " @SuppressWarnings(\"unchecked\")\n" + |
| " void bar(List list) {\n" + |
| " List<String> ls2 = list;\n" + |
| " }\n" + |
| " Zork z;\n" + |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler15/src/X.java (at line 5)\n" + |
| " List<String> ls1 = list;\n" + |
| " ^^^^\n" + |
| "Type safety: The expression of type List needs unchecked conversion to conform to List<String>\n" + |
| "----------\n" + |
| "2. ERROR in /Reconciler15/src/X.java (at line 11)\n" + |
| " Zork z;\n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (otherCopy != null) |
| otherCopy.discardWorkingCopy(); |
| } |
| } |
| /* |
| * Ensure that warning are suppressed by an @SuppressWarning annotation. |
| */ |
| public void testSuppressWarnings3() throws JavaModelException { |
| ICompilationUnit otherCopy = null; |
| try { |
| otherCopy = getWorkingCopy( |
| "/Reconciler15/src/java/util/HashMap.java", |
| "package java.util;\n" + |
| "public class HashMap implements Map {\n" + |
| "}\n", |
| this.wcOwner |
| ); |
| setUp15WorkingCopy("/Reconciler15/src/X.java", this.wcOwner); |
| setWorkingCopyContents( |
| "import java.util.*;\n" + |
| "@SuppressWarnings(\"unchecked\")\n" + |
| "public class X {\n" + |
| " void foo() {\n" + |
| " Map<String, String>[] map = new HashMap[10];\n" + |
| " }\n" + |
| " Zork z;\n" + |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler15/src/X.java (at line 7)\n" + |
| " Zork z;\n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (otherCopy != null) |
| otherCopy.discardWorkingCopy(); |
| } |
| } |
| /* |
| * Ensure that warning are suppressed by an @SuppressWarnings annotation. |
| */ |
| public void testSuppressWarnings4() throws JavaModelException { |
| ICompilationUnit otherCopy = null; |
| try { |
| otherCopy = getWorkingCopy( |
| "/Reconciler15/src/X.java", |
| "/** @deprecated */\n" + |
| "public class X {\n" + |
| " void foo(){}\n" + |
| "}\n", |
| this.wcOwner |
| ); |
| setUp15WorkingCopy("/Reconciler15/src/Y.java", this.wcOwner); |
| setWorkingCopyContents( |
| "public class Y extends X {\n" + |
| " @SuppressWarnings(\"all\")\n" + |
| " void foo(){ super.foo(); }\n" + |
| " Zork z;\n" + |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler15/src/Y.java (at line 1)\n" + |
| " public class Y extends X {\n" + |
| " ^\n" + |
| "The type X is deprecated\n" + |
| "----------\n" + |
| "2. ERROR in /Reconciler15/src/Y.java (at line 4)\n" + |
| " Zork z;\n" + |
| " ^^^^\n" + |
| "Zork cannot be resolved to a type\n" + |
| "----------\n"); |
| } finally { |
| if (otherCopy != null) |
| otherCopy.discardWorkingCopy(); |
| } |
| } |
| /** |
| * Ensure that an unhandled exception is detected. |
| */ |
| public void testUnhandledException() throws JavaModelException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " throw new Exception();\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" + |
| " throw new Exception();\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^^\n" + |
| "Unhandled exception type Exception\n" + |
| "----------\n" |
| ); |
| } |
| /** |
| * Check that forcing a make consistent action is leading the next reconcile to not notice changes. |
| */ |
| public void testMakeConsistentFoolingReconciler() throws JavaModelException { |
| setWorkingCopyContents(""); |
| this.workingCopy.makeConsistent(null); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null); |
| assertWorkingCopyDeltas( |
| "Should have got NO delta", |
| "" |
| ); |
| } |
| /** |
| * Test bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=60689 |
| * AST on reconcile: AST without Javadoc comments created |
| * @deprecated using deprecated code |
| */ |
| public void testBug60689() throws JavaModelException { |
| setWorkingCopyContents("public class X {\n" + |
| " /**\n" + |
| " * Returns the length of the string representing the number of \n" + |
| " * indents in the given string <code>line</code>. Returns \n" + |
| " * <code>-1<code> if the line isn't prefixed with an indent of\n" + |
| " * the given number of indents. \n" + |
| " */\n" + |
| " public static int computeIndentLength(String line, int numberOfIndents, int tabWidth) {\n" + |
| " return 0;\n" + |
| "}" |
| ); |
| org.eclipse.jdt.core.dom.CompilationUnit testCU = this.workingCopy.reconcile(AST.JLS2, true, null, null); |
| assertNotNull("We should have a comment!", testCU.getCommentList()); |
| assertEquals("We should have 1 comment!", 1, testCU.getCommentList().size()); |
| testCU = this.workingCopy.reconcile(AST.JLS2, true, null, null); |
| assertNotNull("We should have a comment!", testCU.getCommentList()); |
| assertEquals("We should have one comment!", 1, testCU.getCommentList().size()); |
| } |
| /* |
| * Ensures that a working copy in a 1.4 project that references a 1.5 project can be reconciled without error. |
| * (regression test for bug 98434 A non-1.5 project with 1.5 projects in the classpath does not show methods with generics) |
| */ |
| public void testTwoProjectsWithDifferentCompliances() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| try { |
| createJavaProject("P1", new String[] {""}, new String[] {"JCL15_LIB"}, "", "1.5"); |
| createFolder("/P1/p"); |
| createFile( |
| "/P1/p/X.java", |
| "package p;\n" + |
| "public class X {\n" + |
| " void foo(Class<String> c) {\n" + |
| " }\n" + |
| "}" |
| ); |
| |
| createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] {"/P1"}, "", "1.4"); |
| createFolder("/P2/p"); |
| this.workingCopy = getWorkingCopy("/P2/p/Y.java", "", this.wcOwner); |
| setWorkingCopyContents( |
| "package p;\n" + |
| "public class Y {\n" + |
| " void bar(Class c) {\n" + |
| " new X().foo(c);\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force pb detection*/, this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProjects(new String[] {"P1", "P2"}); |
| } |
| } |
| /* |
| * Ensures that a method that has a type parameter with bound can be overriden in another working copy. |
| * (regression test for bug 76780 [model] return type not recognized correctly on some generic methods) |
| */ |
| public void testTypeParameterWithBound() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| ICompilationUnit workingCopy1 = null; |
| try { |
| workingCopy1 = getWorkingCopy( |
| "/Reconciler15/src/test/I.java", |
| "package test;\n"+ |
| "public interface I {\n"+ |
| " <T extends I> void foo(T t);\n"+ |
| "}\n", |
| this.wcOwner |
| ); |
| |
| this.problemRequestor = new ProblemRequestor(); |
| this.workingCopy = getWorkingCopy("Reconciler15/src/test/X.java", "", this.wcOwner); |
| setWorkingCopyContents( |
| "package test;\n"+ |
| "public class X implements I {\n"+ |
| " public <T extends I> void foo(T t) {\n"+ |
| " }\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (workingCopy1 != null) { |
| workingCopy1.discardWorkingCopy(); |
| } |
| } |
| } |
| /* |
| * Ensures that a method that has a type parameter starting with $ can be reconciled against. |
| * (regression test for bug 91709 [1.5][model] Quick Fix Error but no Problem Reported) |
| */ |
| public void testTypeParameterStartingWithDollar() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| ICompilationUnit workingCopy1 = null; |
| try { |
| workingCopy1 = getWorkingCopy( |
| "/Reconciler15/src/test/Y.java", |
| "package test;\n"+ |
| "public class Y<$T> {\n"+ |
| " void foo($T t);\n"+ |
| "}\n", |
| this.wcOwner |
| ); |
| |
| this.problemRequestor = new ProblemRequestor(); |
| this.workingCopy = getWorkingCopy("Reconciler15/src/test/X.java", "", this.wcOwner); |
| setWorkingCopyContents( |
| "package test;\n"+ |
| "public class X {\n"+ |
| " public void bar() {\n"+ |
| " new Y<String>().foo(\"\");\n" + |
| " }\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (workingCopy1 != null) { |
| workingCopy1.discardWorkingCopy(); |
| } |
| } |
| } |
| /* |
| * Ensures that a working copy with a type with a dollar name can be reconciled without errors. |
| * (regression test for bug 117121 Can't create class called A$B in eclipse) |
| */ |
| public void testTypeWithDollarName() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| try { |
| String contents = |
| "package p1;\n" + |
| "public class Y$Z {\n" + |
| "}"; |
| createFile( |
| "/Reconciler/src/p1/Y$Z.java", |
| contents |
| ); |
| this.problemRequestor = new ProblemRequestor(); |
| this.workingCopy = getCompilationUnit("Reconciler/src/p1/Y$Z.java").getWorkingCopy(this.wcOwner, null); |
| |
| this.problemRequestor.initialize(contents.toCharArray()); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteFile("/Reconciler/src/p1/Y$Z.java"); |
| } |
| } |
| /* |
| * Ensures that a working copy with a type with a dollar name can be reconciled against without errors. |
| * (regression test for bug 125301 Handling of classes with $ in class name.) |
| */ |
| public void testTypeWithDollarName2() throws CoreException { |
| ICompilationUnit workingCopy2 = null; |
| try { |
| WorkingCopyOwner owner = this.workingCopy.getOwner(); |
| workingCopy2 = getWorkingCopy( |
| "/Reconciler/src/p1/Y$Z.java", |
| "package p1;\n" + |
| "public class Y$Z {\n" + |
| "}", |
| owner |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " Y$Z field;\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, owner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (workingCopy2 != null) |
| workingCopy2.discardWorkingCopy(); |
| } |
| } |
| /* |
| * Ensures that a working copy with a type with a dollar name can be reconciled against without errors. |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=232803 ) |
| */ |
| public void testTypeWithDollarName3() throws CoreException { |
| ICompilationUnit workingCopy2 = null; |
| try { |
| WorkingCopyOwner owner = this.workingCopy.getOwner(); |
| workingCopy2 = getWorkingCopy( |
| "/Reconciler/src/p1/Cl$ss.java", |
| "package p1;\n" + |
| "public interface Cl$ss {\n" + |
| " public void test(Cl$ss c);\n" + |
| " public void foo();\n" + |
| "}", |
| owner |
| ); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " void m(Cl$ss c2) {\n" + |
| " c2.test(c2);\n" + |
| " c2.foo();\n" + |
| " }\n" + |
| "}" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, owner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (workingCopy2 != null) |
| workingCopy2.discardWorkingCopy(); |
| } |
| } |
| /* |
| * Ensures that a varargs method can be referenced from another working copy. |
| */ |
| public void testVarargs() throws CoreException { |
| this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp() |
| this.workingCopy = null; |
| ICompilationUnit workingCopy1 = null; |
| try { |
| workingCopy1 = getWorkingCopy( |
| "/Reconciler15/src/test/X.java", |
| "package test;\n"+ |
| "public class X {\n"+ |
| " void bar(String ... args) {}\n"+ |
| "}\n", |
| this.wcOwner |
| ); |
| |
| this.problemRequestor = new ProblemRequestor(); |
| this.workingCopy = getWorkingCopy("Reconciler15/src/test/Y.java", "", this.wcOwner); |
| setWorkingCopyContents( |
| "package test;\n"+ |
| "public class Y {\n"+ |
| " void foo(){\n"+ |
| " X someX = new X();\n"+ |
| " someX.bar(\"a\", \"b\");\n"+ |
| " }\n"+ |
| "}\n" |
| ); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null); |
| |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (workingCopy1 != null) { |
| workingCopy1.discardWorkingCopy(); |
| } |
| } |
| } |
| |
| /** |
| * Bug 114338:[javadoc] Reconciler reports wrong javadoc warning (missing return type) |
| * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=114338" |
| * |
| */ |
| public void testBug114338() throws CoreException { |
| // Set initial CU content |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "public class X {\n" + |
| " /**\n" + |
| " * @return a\n" + |
| " */\n" + |
| " boolean get() {\n" + |
| " return false;\n" + |
| " }\n" + |
| "}"); |
| this.workingCopy.reconcile(JLS3_INTERNAL, true, this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| |
| // Modify content |
| String contents = |
| "package p1;\n" + |
| "public class X {\n" + |
| " /**\n" + |
| " * @return boolean\n" + |
| " */\n" + |
| " boolean get() {\n" + |
| " return false;\n" + |
| " }\n" + |
| "}"; |
| setWorkingCopyContents(contents); |
| this.workingCopy.reconcile(JLS3_INTERNAL, true, this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } |
| |
| /** |
| * Bug 36032:[plan] JavaProject.findType() fails to find second type in source file |
| * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=36032" |
| */ |
| public void testBug36032a() throws CoreException, InterruptedException { |
| try { |
| // Resources creation |
| createJavaProject("P", new String[] {""}, new String[] {"JCL_LIB"}, "bin"); |
| String source = |
| "public class Test {\n" + |
| " public static void main(String[] args) {\n" + |
| " new SFoo().foo();\n" + |
| " }\n" + |
| "}\n"; |
| this.createFile( |
| "/P/Foo.java", |
| "class SFoo { void foo() {} }\n" |
| ); |
| this.createFile( |
| "/P/Test.java", |
| source |
| ); |
| |
| // Get compilation unit and reconcile it |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopy = getCompilationUnit("/P/Test.java").getWorkingCopy(this.wcOwner, null); |
| this.workingCopy.getBuffer().setContents(source); |
| this.workingCopy.reconcile(JLS3_INTERNAL, true, null, null); |
| assertNoProblem(sourceChars, this.workingCopy); |
| |
| // Add new secondary type |
| this.createFile( |
| "/P/Bar.java", |
| "class SBar{ void bar() {} }\n" |
| ); |
| source = |
| "public class Test {\n" + |
| " public static void main(String[] args) {\n" + |
| " new SFoo().foo();\n" + |
| " new SBar().bar();\n" + |
| " }\n" + |
| "}\n"; |
| |
| // Reconcile with modified source |
| sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopy.getBuffer().setContents(source); |
| this.workingCopy.reconcile(JLS3_INTERNAL, true, null, null); |
| assertNoProblem(sourceChars, this.workingCopy); |
| } finally { |
| deleteProject("P"); |
| } |
| } |
| public void testBug36032b() throws CoreException, InterruptedException { |
| try { |
| // Resources creation |
| createJavaProject("P", new String[] {""}, new String[] {"JCL_LIB"}, "bin"); |
| String source = |
| "public class Test {\n" + |
| " public static void main(String[] args) {\n" + |
| " new SFoo().foo();\n" + |
| " new SBar().bar();\n" + |
| " }\n" + |
| "}\n"; |
| createFile( |
| "/P/Foo.java", |
| "class SFoo { void foo() {} }\n" |
| ); |
| createFile( |
| "/P/Test.java", |
| source |
| ); |
| createFile( |
| "/P/Bar.java", |
| "class SBar{ void bar() {} }\n" |
| ); |
| |
| // Get compilation unit and reconcile it |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopy = getCompilationUnit("/P/Test.java").getWorkingCopy(this.wcOwner, null); |
| this.workingCopy.getBuffer().setContents(source); |
| this.workingCopy.reconcile(JLS3_INTERNAL, true, null, null); |
| assertNoProblem(sourceChars, this.workingCopy); |
| |
| // Delete secondary type => should get a problem |
| waitUntilIndexesReady(); |
| deleteFile("/P/Bar.java"); |
| this.problemRequestor.initialize(source.toCharArray()); |
| this.workingCopy.reconcile(JLS3_INTERNAL, true, null, null); |
| assertEquals("Working copy should not find secondary type 'Bar'!", 1, this.problemRequestor.problemCount); |
| assertProblems("Working copy should have problem!", |
| "----------\n" + |
| "1. ERROR in /P/Test.java (at line 4)\n" + |
| " new SBar().bar();\n" + |
| " ^^^^\n" + |
| "SBar cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| |
| // Fix the problem |
| source = |
| "public class Test {\n" + |
| " public static void main(String[] args) {\n" + |
| " new SFoo().foo();\n" + |
| " }\n" + |
| "}\n"; |
| sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopy.getBuffer().setContents(source); |
| this.workingCopy.reconcile(JLS3_INTERNAL, true, null, null); |
| assertNoProblem(sourceChars, this.workingCopy); |
| } finally { |
| deleteProject("P"); |
| } |
| } |
| // Secondary types used through multiple projects |
| public void testBug36032c() throws CoreException, InterruptedException { |
| try { |
| // Create first project |
| createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin"); |
| createFolder("/P1/test"); |
| createFile( |
| "/P1/test/Foo.java", |
| "package test;\n" + |
| "class Secondary{ void foo() {} }\n" |
| ); |
| createFile( |
| "/P1/test/Test1.java", |
| "package test;\n" + |
| "public class Test1 {\n" + |
| " public static void main(String[] args) {\n" + |
| " new Secondary().foo();\n" + |
| " }\n" + |
| "}\n" |
| ); |
| |
| // Create second project |
| createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin"); |
| String source = |
| "package test;\n" + |
| "public class Test2 {\n" + |
| " public static void main(String[] args) {\n" + |
| " new Secondary().foo();\n" + |
| " }\n" + |
| "}\n"; |
| createFolder("/P2/test"); |
| createFile( |
| "/P2/test/Test2.java", |
| source |
| ); |
| |
| // Get compilation unit and reconcile it => expect no error |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopy = getCompilationUnit("/P2/test/Test2.java").getWorkingCopy(this.wcOwner, null); |
| this.workingCopy.getBuffer().setContents(source); |
| this.workingCopy.reconcile(JLS3_INTERNAL, true, null, null); |
| assertNoProblem(sourceChars, this.workingCopy); |
| } finally { |
| deleteProject("P1"); |
| deleteProject("P2"); |
| } |
| } |
| /** |
| * Bug 118823: [model] Secondary types cache not reset while removing _all_ secondary types from CU |
| * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=118823" |
| */ |
| public void testBug118823() throws CoreException, InterruptedException, IOException { |
| try { |
| // Resources creation |
| createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin"); |
| String source = "class Test {}\n"; |
| createFile( |
| "/P1/Test.java", |
| source |
| ); |
| createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin"); |
| String source2 = |
| "class A {\n" + |
| " Secondary s;\n" + |
| "}\n"; |
| createFile( |
| "/P2/A.java", |
| source2 |
| ); |
| waitUntilIndexesReady(); |
| this.workingCopies = new ICompilationUnit[2]; |
| |
| // Get first working copy and verify that there's no error |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/P1/Test.java").getWorkingCopy(this.wcOwner, null); |
| assertNoProblem(sourceChars, this.workingCopies[0]); |
| |
| // Get second working copy and verify that there's one error (missing secondary type) |
| this.problemRequestor.initialize(source2.toCharArray()); |
| this.workingCopies[1] = getCompilationUnit("/P2/A.java").getWorkingCopy(this.wcOwner, null); |
| assertEquals("Working copy should not find secondary type 'Secondary'!", 1, this.problemRequestor.problemCount); |
| assertProblems("Working copy should have problem!", |
| "----------\n" + |
| "1. ERROR in /P2/A.java (at line 2)\n" + |
| " Secondary s;\n" + |
| " ^^^^^^^^^\n" + |
| "Secondary cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| |
| // Delete file and recreate it with secondary |
| final String source1 = |
| "public class Test {}\n" + |
| "class Secondary{}\n"; |
| getWorkspace().run( |
| new IWorkspaceRunnable() { |
| public void run(IProgressMonitor monitor) throws CoreException { |
| deleteFile("/P1/Test.java"); |
| createFile( |
| "/P1/Test.java", |
| source1 |
| ); |
| } |
| }, |
| null |
| ); |
| |
| // Get first working copy and verify that there's still no error |
| sourceChars = source1.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0].getBuffer().setContents(source1); |
| this.workingCopies[0].reconcile(JLS3_INTERNAL, |
| 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); |
| assertNoProblem(sourceChars, this.workingCopies[0]); |
| |
| // Get second working copy and verify that there's any longer error |
| sourceChars = source2.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[1].getBuffer().setContents(source2); |
| this.workingCopies[1].reconcile(JLS3_INTERNAL, |
| 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); |
| assertNoProblem(sourceChars, this.workingCopies[1]); |
| } finally { |
| deleteProject("P1"); |
| deleteProject("P2"); |
| } |
| } |
| public void testBug118823b() throws CoreException, InterruptedException { |
| try { |
| // Resources creation |
| createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin"); |
| String source1 = "class Test {}\n"; |
| createFile( |
| "/P1/Test.java", |
| source1 |
| ); |
| createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin"); |
| String source2 = |
| "class A {\n" + |
| " Secondary s;\n" + |
| "}\n"; |
| createFile( |
| "/P2/A.java", |
| source2 |
| ); |
| waitUntilIndexesReady(); |
| this.workingCopies = new ICompilationUnit[2]; |
| |
| // Get first working copy and verify that there's no error |
| char[] sourceChars = source1.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/P1/Test.java").getWorkingCopy(this.wcOwner, null); |
| assertNoProblem(sourceChars, this.workingCopies[0]); |
| |
| // Get second working copy and verify that there's one error (missing secondary type) |
| this.problemRequestor.initialize(source2.toCharArray()); |
| this.workingCopies[1] = getCompilationUnit("/P2/A.java").getWorkingCopy(this.wcOwner, null); |
| assertEquals("Working copy should not find secondary type 'Secondary'!", 1, this.problemRequestor.problemCount); |
| assertProblems("Working copy should have problem!", |
| "----------\n" + |
| "1. ERROR in /P2/A.java (at line 2)\n" + |
| " Secondary s;\n" + |
| " ^^^^^^^^^\n" + |
| "Secondary cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| |
| // Modify first working copy and verify that there's still no error |
| source1 = |
| "public class Test {}\n" + |
| "class Secondary{}\n"; |
| sourceChars = source1.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0].getBuffer().setContents(source1); |
| this.workingCopies[0].reconcile(JLS3_INTERNAL, |
| 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); |
| this.workingCopies[0].commitWorkingCopy(true, null); |
| assertNoProblem(sourceChars, this.workingCopies[0]); |
| |
| // Get second working copy and verify that there's any longer error |
| sourceChars = source2.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[1].getBuffer().setContents(source2); |
| this.workingCopies[1].reconcile(JLS3_INTERNAL, |
| 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); |
| assertNoProblem(sourceChars, this.workingCopies[1]); |
| } finally { |
| deleteProject("P1"); |
| deleteProject("P2"); |
| } |
| } |
| public void testBug118823c() throws CoreException, InterruptedException { |
| try { |
| // Resources creation |
| createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin"); |
| String source1 = "class Test {}\n"; |
| createFile( |
| "/P1/Test.java", |
| source1 |
| ); |
| createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin"); |
| String source2 = |
| "class A {\n" + |
| " Secondary s;\n" + |
| "}\n"; |
| createFile( |
| "/P2/A.java", |
| source2 |
| ); |
| waitUntilIndexesReady(); |
| this.workingCopies = new ICompilationUnit[2]; |
| |
| // Get first working copy and verify that there's no error |
| char[] sourceChars = source1.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/P1/Test.java").getWorkingCopy(this.wcOwner, null); |
| assertNoProblem(sourceChars, this.workingCopies[0]); |
| |
| // Get second working copy and verify that there's one error (missing secondary type) |
| this.problemRequestor.initialize(source2.toCharArray()); |
| this.workingCopies[1] = getCompilationUnit("/P2/A.java").getWorkingCopy(this.wcOwner, null); |
| assertEquals("Working copy should not find secondary type 'Secondary'!", 1, this.problemRequestor.problemCount); |
| assertProblems("Working copy should have problem!", |
| "----------\n" + |
| "1. ERROR in /P2/A.java (at line 2)\n" + |
| " Secondary s;\n" + |
| " ^^^^^^^^^\n" + |
| "Secondary cannot be resolved to a type\n" + |
| "----------\n" |
| ); |
| |
| // Delete file and recreate it with secondary |
| deleteFile("/P1/Test.java"); |
| source1 = |
| "public class Test {}\n" + |
| "class Secondary{}\n"; |
| createFile( |
| "/P1/Test.java", |
| source1 |
| ); |
| |
| // Get first working copy and verify that there's still no error |
| sourceChars = source1.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0].getBuffer().setContents(source1); |
| this.workingCopies[0].reconcile(JLS3_INTERNAL, |
| 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); |
| this.workingCopies[0].commitWorkingCopy(true, null); |
| assertNoProblem(sourceChars, this.workingCopies[0]); |
| |
| // Get second working copy and verify that there's any longer error |
| sourceChars = source2.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[1].getBuffer().setContents(source2); |
| this.workingCopies[1].reconcile(JLS3_INTERNAL, |
| 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); |
| assertNoProblem(sourceChars, this.workingCopies[1]); |
| } finally { |
| deleteProject("P1"); |
| deleteProject("P2"); |
| } |
| } |
| |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=107931 |
| // won't be fixed; this test watches the current behavior in case we change |
| // our mind |
| public void test1001() throws CoreException, InterruptedException, IOException { |
| try { |
| // Resources creation |
| String sources[] = new String[3]; |
| char[] sourcesAsCharArrays[] = new char[3][]; |
| createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin"); |
| sources[0] = "class X {}\n"; |
| createFile( |
| "/P1/X.java", |
| sources[0] |
| ); |
| createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin"); |
| sources[1] = |
| "interface I {\n" + |
| " void foo();\n" + |
| " void bar(X p);\n" + |
| "}\n"; |
| createFile( |
| "/P2/I.java", |
| sources[1] |
| ); |
| createJavaProject("P3", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P2" }, "bin"); |
| sources[2] = |
| "class Y implements I {\n" + |
| " // public void foo() { }\n" + |
| " // public void bar(X p) { }\n" + |
| "}\n"; |
| createFile( |
| "/P3/Y.java", |
| sources[2] |
| ); |
| for (int i = 0 ; i < sources.length ; i++) { |
| sourcesAsCharArrays[i] = sources[i].toCharArray(); |
| } |
| waitUntilIndexesReady(); |
| this.workingCopies = new ICompilationUnit[3]; |
| |
| // Get first working copy and verify that there's no error |
| this.problemRequestor.initialize(sourcesAsCharArrays[0]); |
| this.workingCopies[0] = getCompilationUnit("/P1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertNoProblem(sourcesAsCharArrays[0], this.workingCopies[0]); |
| |
| // Get second working copy and verify that there's no error |
| this.problemRequestor.initialize(sourcesAsCharArrays[1]); |
| this.workingCopies[1] = getCompilationUnit("/P2/I.java").getWorkingCopy(this.wcOwner, null); |
| assertNoProblem(sourcesAsCharArrays[1], this.workingCopies[1]); |
| |
| // Get third working copy and verify that all expected errors are here |
| this.problemRequestor.initialize(sourcesAsCharArrays[2]); |
| this.workingCopies[2] = getCompilationUnit("/P3/Y.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems("Working copy should have problems:", |
| "----------\n" + |
| "1. ERROR in /P3/Y.java (at line 1)\n" + |
| " class Y implements I {\n" + |
| " ^\n" + |
| "The type Y must implement the inherited abstract method I.bar(X)\n" + |
| "----------\n" + |
| "2. ERROR in /P3/Y.java (at line 1)\n" + |
| " class Y implements I {\n" + |
| " ^\n" + |
| "The type Y must implement the inherited abstract method I.foo()\n" + |
| "----------\n"); |
| } finally { |
| deleteProject("P1"); |
| deleteProject("P2"); |
| deleteProject("P3"); |
| } |
| } |
| |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=107931 |
| // variant: having all needed projects on the classpath solves the issue |
| public void test1002() throws CoreException, InterruptedException, IOException { |
| try { |
| // Resources creation |
| String sources[] = new String[3]; |
| char[] sourcesAsCharArrays[] = new char[3][]; |
| createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin"); |
| sources[0] = "class X {}\n"; |
| createFile( |
| "/P1/X.java", |
| sources[0] |
| ); |
| createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin"); |
| sources[1] = |
| "interface I {\n" + |
| " void foo();\n" + |
| " void bar(X p);\n" + |
| "}\n"; |
| createFile( |
| "/P2/I.java", |
| sources[1] |
| ); |
| createJavaProject("P3", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" /* compare with test1001 */, "/P2" }, "bin"); |
| sources[2] = |
| "class Y implements I {\n" + |
| " // public void foo() { }\n" + |
| " // public void bar(X p) { }\n" + |
| "}\n"; |
| createFile( |
| "/P3/Y.java", |
| sources[2] |
| ); |
| for (int i = 0 ; i < sources.length ; i++) { |
| sourcesAsCharArrays[i] = sources[i].toCharArray(); |
| } |
| waitUntilIndexesReady(); |
| this.workingCopies = new ICompilationUnit[3]; |
| |
| // Get first working copy and verify that there's no error |
| this.problemRequestor.initialize(sourcesAsCharArrays[0]); |
| this.workingCopies[0] = getCompilationUnit("/P1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertNoProblem(sourcesAsCharArrays[0], this.workingCopies[0]); |
| |
| // Get second working copy and verify that there's no error |
| this.problemRequestor.initialize(sourcesAsCharArrays[1]); |
| this.workingCopies[1] = getCompilationUnit("/P2/I.java").getWorkingCopy(this.wcOwner, null); |
| assertNoProblem(sourcesAsCharArrays[1], this.workingCopies[1]); |
| |
| // Get third working copy and verify that all expected errors are here |
| this.problemRequestor.initialize(sourcesAsCharArrays[2]); |
| this.workingCopies[2] = getCompilationUnit("/P3/Y.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems("Working copy should have problems:", |
| "----------\n" + |
| "1. ERROR in /P3/Y.java (at line 1)\n" + |
| " class Y implements I {\n" + |
| " ^\n" + |
| "The type Y must implement the inherited abstract method I.bar(X)\n" + |
| "----------\n" + |
| "2. ERROR in /P3/Y.java (at line 1)\n" + |
| " class Y implements I {\n" + |
| " ^\n" + |
| "The type Y must implement the inherited abstract method I.foo()\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProject("P1"); |
| deleteProject("P2"); |
| deleteProject("P3"); |
| } |
| } |
| /* |
| * Ensure that fallthrough diagnostics are silenced by $FALL-THROUGH$ comments |
| */ |
| public void testFallthroughDiagnosis() throws CoreException, InterruptedException { |
| try { |
| // Resources creation |
| IJavaProject p1 = createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin"); |
| p1.setOption(JavaCore.COMPILER_PB_FALLTHROUGH_CASE, JavaCore.ERROR); |
| String source = |
| "public class X {\n" + |
| " void foo(int i) {\n" + |
| " switch(i) {\n" + |
| " case 0:\n" + |
| " i ++;\n" + |
| " // $FALL-THROUGH$\n" + |
| " case 1:\n" + |
| " i++;\n" + |
| " /* $FALL-THROUGH$ */\n" + |
| " case 2:\n" + |
| " i++;\n" + |
| " case 3:\n" + |
| " }\n" + |
| " }\n" + |
| "}\n"; |
| |
| createFile("/P1/X.java", source); |
| this.workingCopies = new ICompilationUnit[1]; |
| |
| // Get first working copy and verify that there's no error |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/P1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems("Working copy should have problems:", |
| "----------\n" + |
| "1. ERROR in /P1/X.java (at line 12)\n" + |
| " case 3:\n" + |
| " ^^^^^^\n" + |
| "Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProject("P1"); |
| } |
| } |
| /* |
| * Ensure that the option ICompilationUnit.IGNORE_METHOD_BODIES is honored |
| */ |
| public void testIgnoreMethodBodies1() throws CoreException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;" + |
| "public class X {\n" + |
| " public int foo() {\n" + // force an error by not returning |
| " int i = 0;\n" + |
| " }\n" + |
| "}"); |
| org.eclipse.jdt.core.dom.CompilationUnit ast = this.workingCopy.reconcile(JLS3_INTERNAL, ICompilationUnit.IGNORE_METHOD_BODIES, null, null); |
| // X.foo() not returning any value should not be reported |
| assertProblems("Working copy should have problems:", |
| "----------\n" + |
| "1. WARNING in /Reconciler/src/p1/X.java (at line 2)\n"+ |
| " import p2.*;public class X {\n" + |
| " ^^\n" + |
| "The import p2 is never used\n"+ |
| "----------\n" |
| ); |
| // statement declaring i should not be in the AST |
| assertASTNodeEquals( |
| "Unexpected participant ast", |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public int foo(){\n" + |
| " }\n" + |
| "}\n", |
| ast |
| ); |
| } |
| public void testIgnoreMethodBodies2() throws CoreException { |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " int i = 0;\n" + |
| " }\n" + |
| " public int bar() {\n" + |
| " int i = 0;\n" + |
| " new X() /*start*/{\n" + |
| " }/*end*/;" + |
| " }\n" + |
| "}"); |
| org.eclipse.jdt.core.dom.CompilationUnit ast = this.workingCopy.reconcile(JLS3_INTERNAL, ICompilationUnit.IGNORE_METHOD_BODIES, null, null); |
| // methods with anonymous classes should have their statements intact |
| assertASTNodeEquals( |
| "Unexpected ast", |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo(){\n" + |
| " }\n" + |
| " public int bar(){\n" + |
| " }\n" + |
| "}\n", |
| ast |
| ); |
| } |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=130000 |
| public void testIgnoreMethodBodies3() throws CoreException { |
| new ReconcileParticipant2(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " int i = 0;\n" + |
| " }\n" + |
| " public int bar() {\n" + |
| " int i = 0;\n" + |
| " new X() {\n" + |
| " };" + |
| " }\n" + |
| "}"); |
| org.eclipse.jdt.core.dom.CompilationUnit ast = this.workingCopy.reconcile( |
| JLS3_INTERNAL, |
| ICompilationUnit.IGNORE_METHOD_BODIES | ICompilationUnit.ENABLE_STATEMENTS_RECOVERY, |
| null, |
| null); |
| // methods with anonymous classes should have their statements intact |
| assertASTNodeEquals( |
| "Unexpected ast", |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo(){\n" + |
| " }\n" + |
| " public int bar(){\n" + |
| " }\n" + |
| "}\n", |
| ast |
| ); |
| } |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=130000 |
| public void testIgnoreMethodBodies4() throws CoreException { |
| new ReconcileParticipant3(); |
| setWorkingCopyContents( |
| "package p1;\n" + |
| "import p2.*;" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " int i = 0;\n" + |
| " }\n" + |
| " public int bar() {\n" + |
| " int i = 0;\n" + |
| " new X() {\n" + |
| " };" + |
| " }\n" + |
| "}"); |
| org.eclipse.jdt.core.dom.CompilationUnit ast = this.workingCopy.reconcile( |
| JLS3_INTERNAL, |
| ICompilationUnit.IGNORE_METHOD_BODIES, |
| null, |
| null); |
| // methods with anonymous classes should have their statements intact |
| assertASTNodeEquals( |
| "Unexpected ast", |
| "package p1;\n" + |
| "import p2.*;\n" + |
| "public class X {\n" + |
| " public void foo(){\n" + |
| " }\n" + |
| " public int bar(){\n" + |
| " }\n" + |
| "}\n", |
| ast |
| ); |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259 |
| public void testGenericAPIUsageFromA14Project() throws CoreException { |
| IJavaProject project14 = null; |
| IJavaProject project15 = null; |
| try { |
| project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| createFolder("/Reconciler15API/src/p2"); |
| createFile( |
| "/Reconciler15API/src/p2/BundleContext.java", |
| "package p2;\n" + |
| "public class BundleContext {\n" + |
| " public <S> S getService(S s) {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}" |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); |
| |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| IClasspathEntry[] oldClasspath = project14.getRawClasspath(); |
| int oldLength = oldClasspath.length; |
| IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; |
| System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); |
| newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API")); |
| project14.setRawClasspath(newClasspath, null); |
| |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "import p2.BundleContext;\n" + |
| "public class X {\n" + |
| " public static void main(BundleContext context, String string) {\n" + |
| " String s = (String) context.getService(string); \n" + |
| " }\n" + |
| "}"; |
| |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler1415/src/p1/X.java (at line 5)\n" + |
| " String s = (String) context.getService(string); \n" + |
| " ^\n" + |
| "The value of the local variable s is not used\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259 (same as above, but with a JSR14 target) |
| public void testGenericAPIUsageFromA14Project2() throws CoreException { |
| IJavaProject project14 = null; |
| IJavaProject project15 = null; |
| try { |
| project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| createFolder("/Reconciler15API/src/p2"); |
| createFile( |
| "/Reconciler15API/src/p2/BundleContext.java", |
| "package p2;\n" + |
| "public class BundleContext {\n" + |
| " public <S> S getService(S s) {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}" |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| IClasspathEntry[] oldClasspath = project14.getRawClasspath(); |
| int oldLength = oldClasspath.length; |
| IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; |
| System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); |
| newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API")); |
| project14.setRawClasspath(newClasspath, null); |
| |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "import p2.BundleContext;\n" + |
| "public class X {\n" + |
| " public static void main(BundleContext context, String string) {\n" + |
| " String s = (String) context.getService(string); \n" + |
| " }\n" + |
| "}"; |
| |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler1415/src/p1/X.java (at line 5)\n" + |
| " String s = (String) context.getService(string); \n" + |
| " ^\n" + |
| "The value of the local variable s is not used\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 |
| public void testGenericAPIUsageFromA14Project3() throws CoreException { |
| IJavaProject project14 = null; |
| IJavaProject project15 = null; |
| try { |
| project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| createFolder("/Reconciler15API/src/p2"); |
| createFile( |
| "/Reconciler15API/src/p2/X.java", |
| "package p2;\n" + |
| "import java.util.Collection;\n" + |
| "import java.util.Iterator;\n" + |
| "public class X<E> implements Collection<E>{\n" + |
| " public static X getX() {\n" + |
| " return new X();\n" + |
| " }\n" + |
| " public int size() {\n" + |
| " return 0;\n" + |
| " }\n" + |
| " public boolean isEmpty() {\n" + |
| " return false;\n" + |
| " }\n" + |
| " public boolean contains(Object o) {\n" + |
| " return false;\n" + |
| " }\n" + |
| " public Iterator<E> iterator() {\n" + |
| " return null;\n" + |
| " }\n" + |
| " public Object[] toArray() {\n" + |
| " return null;\n" + |
| " }\n" + |
| " public <T> T[] toArray(T[] a) {\n" + |
| " return null;\n" + |
| " }\n" + |
| " public boolean add(E e) {\n" + |
| " return false;\n" + |
| " }\n" + |
| " public boolean remove(Object o) {\n" + |
| " return false;\n" + |
| " }\n" + |
| " public boolean containsAll(Collection<?> c) {\n" + |
| " return false;\n" + |
| " }\n" + |
| " public boolean addAll(Collection<? extends E> c) {\n" + |
| " return false;\n" + |
| " }\n" + |
| " public boolean removeAll(Collection<?> c) {\n" + |
| " return false;\n" + |
| " }\n" + |
| " public boolean retainAll(Collection<?> c) {\n" + |
| " return false;\n" + |
| " }\n" + |
| " public void clear() {\n" + |
| " }\n" + |
| "}\n" |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); |
| |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| IClasspathEntry[] oldClasspath = project14.getRawClasspath(); |
| int oldLength = oldClasspath.length; |
| IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; |
| System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); |
| newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API")); |
| project14.setRawClasspath(newClasspath, null); |
| |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "import java.util.Collection;\n" + |
| "public class X {\n" + |
| " public static void main(String string) {\n" + |
| " Collection c = p2.X.getX(); \n" + |
| " }\n" + |
| "}"; |
| |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler1415/src/p1/X.java (at line 5)\n" + |
| " Collection c = p2.X.getX(); \n" + |
| " ^\n" + |
| "The value of the local variable c is not used\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 (variation: 15 uses 14) |
| public void testGenericAPIUsageFromA14Project4() throws CoreException { |
| IJavaProject project14 = null; |
| IJavaProject project15 = null; |
| try { |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "import java.lang.Comparable;\n" + |
| "public class X implements Comparable {\n" + |
| " public static X getX() {\n" + |
| " return new X();\n" + |
| " }\n" + |
| "}"; |
| |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| createFolder("/Reconciler15API/src/p2"); |
| String otherSource = "package p2;\n" + |
| "public class X { \n" + |
| " private p1.X x = p1.X.getX();\n" + |
| " Comparable<String> y = null;\n" + |
| "}\n"; |
| |
| createFile( |
| "/Reconciler15API/src/p2/X.java", |
| otherSource |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); |
| |
| IClasspathEntry[] oldClasspath = project15.getRawClasspath(); |
| int oldLength = oldClasspath.length; |
| IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; |
| System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); |
| newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler1415")); |
| project15.setRawClasspath(newClasspath, null); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = otherSource.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler15API/src/p2/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler15API/src/p2/X.java (at line 3)\n" + |
| " private p1.X x = p1.X.getX();\n" + |
| " ^\n" + |
| "The value of the field X.x is not used\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=325633 |
| public void testGenericAPIUsageFromA14Project5() throws CoreException { |
| IJavaProject project14 = null; |
| IJavaProject project15 = null; |
| try { |
| project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| createFolder("/Reconciler15API/src/p2"); |
| createFile( |
| "/Reconciler15API/src/p2/List.java", |
| "package p2;\n" + |
| "public class List<T> {}\n" + |
| " public static List<String> [] getArray() {\n" + |
| " return null;\n" + |
| " }\n" + |
| " public static List<String> [] getBackArray(List<String>[] p) {\n" + |
| " return p;\n" + |
| " }\n" + |
| "}" |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); |
| |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| IClasspathEntry[] oldClasspath = project14.getRawClasspath(); |
| int oldLength = oldClasspath.length; |
| IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; |
| System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); |
| newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API")); |
| project14.setRawClasspath(newClasspath, null); |
| |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "import p2.List;\n" + |
| "public class X {\n" + |
| " private List [] l = List.getArray();\n" + |
| " private List [] l2 = List.getBackArray(l);\n" + |
| "}"; |
| |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler1415/src/p1/X.java (at line 5)\n" + |
| " private List [] l2 = List.getBackArray(l);\n" + |
| " ^^\n" + |
| "The value of the field X.l2 is not used\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 |
| public void testGenericAPIUsageFromA14Project6() throws CoreException { |
| IJavaProject project14 = null; |
| IJavaProject project15 = null; |
| try { |
| project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| createFolder("/Reconciler15API/src/p2"); |
| createFile( |
| "/Reconciler15API/src/p2/Y.java", |
| "package p2;\n" + |
| "public abstract class Y implements I<Y> {\n" + |
| " public final Y foo(Object o, J<Y> j) {\n" + |
| " return null;\n" + |
| " }\n" + |
| " public final void bar(Object o, J<Y> j, Y y) {\n" + |
| " }\n" + |
| "}\n" + |
| "interface I<S> {\n" + |
| " public S foo(Object o, J<S> j);\n" + |
| " public void bar(Object o, J<S> j, S s);\n" + |
| "}\n" + |
| "interface J<S> {}\n" |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); |
| |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| IClasspathEntry[] oldClasspath = project14.getRawClasspath(); |
| int oldLength = oldClasspath.length; |
| IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; |
| System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); |
| newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API")); |
| project14.setRawClasspath(newClasspath, null); |
| |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "import p2.Y;\n" + |
| "public class X {\n" + |
| " private int unused = 0;\n" + |
| " public Object foo() {\n" + |
| " return new Y() {};\n" + |
| " }\n" + |
| "}"; |
| |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler1415/src/p1/X.java (at line 4)\n" + |
| " private int unused = 0;\n" + |
| " ^^^^^^\n" + |
| "The value of the field X.unused is not used\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 |
| public void testGenericAPIUsageFromA14Project7() throws CoreException, IOException { |
| IJavaProject project14 = null; |
| IJavaProject project15 = null; |
| try { |
| project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| createFolder("/Reconciler15API/src/p2"); |
| createFile( |
| "/Reconciler15API/src/p2/Y.java", |
| "package p2;\n" + |
| "import java.util.List;\n" + |
| "public class Y<T> extends List<T> {\n" + |
| " public static Y<String> getY() {\n" + |
| " return new Y<String>();\n" + |
| " }\n" + |
| "}\n" |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); |
| |
| addLibrary( |
| project15, |
| "libList15.jar", |
| "libList15src.zip", |
| new String[] { |
| "java/util/List.java", |
| "package java.util;\n" + |
| "public class List<T> {\n" + |
| "}" |
| }, |
| JavaCore.VERSION_1_5 |
| ); |
| |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| addLibrary( |
| project14, |
| "libList14.jar", |
| "libList14src.zip", |
| new String[] { |
| "java/util/List.java", |
| "package java.util;\n" + |
| "public class List {\n" + |
| "}" |
| }, |
| JavaCore.VERSION_1_4 |
| ); |
| |
| IClasspathEntry[] oldClasspath = project14.getRawClasspath(); |
| int oldLength = oldClasspath.length; |
| IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; |
| System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); |
| newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API")); |
| project14.setRawClasspath(newClasspath, null); |
| |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "import java.util.List;\n" + |
| "import p2.Y;\n" + |
| "public class X {\n" + |
| " private static List getList(boolean test) {\n" + |
| " if (test)\n" + |
| " return new Y();\n" + |
| " else\n" + |
| " return Y.getY();\n" + |
| " }\n" + |
| "}"; |
| |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler1415/src/p1/X.java (at line 5)\n" + |
| " private static List getList(boolean test) {\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^\n" + |
| "The method getList(boolean) from the type X is never used locally\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 |
| public void testGenericAPIUsageFromA14Project8() throws CoreException, IOException { |
| IJavaProject project14 = null; |
| IJavaProject project15 = null; |
| try { |
| project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| createFolder("/Reconciler15API/src/p2"); |
| createFile( |
| "/Reconciler15API/src/p2/Y.java", |
| "package p2;\n" + |
| "public class Y<T> extends java.util.List<T> {\n" + |
| " public static Y<String> getY() {\n" + |
| " return new Y<String>();\n" + |
| " }\n" + |
| "}\n" |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); |
| |
| addLibrary( |
| project15, |
| "libList15.jar", |
| "libList15src.zip", |
| new String[] { |
| "java/util/List.java", |
| "package java.util;\n" + |
| "public class List<T> {\n" + |
| "}" |
| }, |
| JavaCore.VERSION_1_5 |
| ); |
| |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| addLibrary( |
| project14, |
| "libList14.jar", |
| "libList14src.zip", |
| new String[] { |
| "java/util/List.java", |
| "package java.util;\n" + |
| "public class List {\n" + |
| "}" |
| }, |
| JavaCore.VERSION_1_4 |
| ); |
| |
| IClasspathEntry[] oldClasspath = project14.getRawClasspath(); |
| int oldLength = oldClasspath.length; |
| IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; |
| System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); |
| newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API")); |
| project14.setRawClasspath(newClasspath, null); |
| |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "import p2.Y;\n" + |
| "public class X {\n" + |
| " private static java.util.List getList(boolean test) {\n" + |
| " if (test)\n" + |
| " return new Y();\n" + |
| " else\n" + |
| " return Y.getY();\n" + |
| " }\n" + |
| "}"; |
| |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler1415/src/p1/X.java (at line 4)\n" + |
| " private static java.util.List getList(boolean test) {\n" + |
| " ^^^^^^^^^^^^^^^^^^^^^\n" + |
| "The method getList(boolean) from the type X is never used locally\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=328775 |
| public void test14ProjectWith15JRE() throws CoreException, IOException { |
| IJavaProject project14 = null; |
| try { |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "public class X {\n" + |
| " int a;\n" + |
| " private Class c = a == 1 ? int.class : long.class;\n" + |
| "}\n"; |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler1415/src/p1/X.java (at line 4)\n" + |
| " private Class c = a == 1 ? int.class : long.class;\n" + |
| " ^\n" + |
| "The value of the field X.c is not used\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329593 |
| public void testJsr14TargetProjectWith14JRE() throws CoreException, IOException { |
| IJavaProject project14 = null; |
| try { |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "public class X {\n" + |
| " public void foo() {\n" + |
| " Class type = null;\n" + |
| " if (type == byte.class)\n" + |
| " return;\n" + |
| " }\n" + |
| "}\n"; |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler1415/src/p1/X.java (at line 6)\n" + |
| " return;\n" + |
| " ^^^^^^^\n" + |
| "Dead code\n" + |
| "----------\n" |
| |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| } |
| } |
| public void testGenericAPIUsageFromA14Project9() throws CoreException { |
| IJavaProject project14 = null; |
| IJavaProject project15 = null; |
| try { |
| project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| createFolder("/Reconciler15API/src/p1"); |
| createFile( |
| "/Reconciler15API/src/p1/Y.java", |
| "package p1;\n" + |
| "public class Y {\n" + |
| " static <T> void foo(List<T> expected) {}\n" + |
| " public static <T> void foo(T expected) {}\n" + |
| "}\n" |
| ); |
| createFile( |
| "/Reconciler15API/src/p1/List.java", |
| "package p1;\n" + |
| "public class List<T> {}\n" |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); |
| |
| project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); |
| project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); |
| project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); |
| |
| IClasspathEntry[] oldClasspath = project14.getRawClasspath(); |
| int oldLength = oldClasspath.length; |
| IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; |
| System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); |
| newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API")); |
| project14.setRawClasspath(newClasspath, null); |
| |
| createFolder("/Reconciler1415/src/p1"); |
| String source = |
| "package p1;\n" + |
| "public class X {\n" + |
| " private int unused = 0;\n" + |
| " X(List l) {\n" + |
| " Y.foo(l);\n" + |
| " }\n" + |
| "}\n"; |
| |
| createFile( |
| "/Reconciler1415/src/p1/X.java", |
| source |
| ); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /Reconciler1415/src/p1/X.java (at line 3)\n" + |
| " private int unused = 0;\n" + |
| " ^^^^^^\n" + |
| "The value of the field X.unused is not used\n" + |
| "----------\n" |
| ); |
| } finally { |
| if (project14 != null) |
| deleteProject(project14); |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=374176 |
| // verify that a reconcile does not result in errors for a CU whose package does not have |
| // default null annotations |
| public void testBug374176() throws CoreException, IOException, InterruptedException { |
| IJavaProject project15 = null; |
| try { |
| project15 = createJavaProject("TestAnnot", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| createFolder("/TestAnnot/src/p1"); |
| String source = "package p1;\n" + |
| "public class Y {\n" + |
| "}\n;"; |
| createFile( |
| "/TestAnnot/src/p1/Y.java", |
| source |
| ); |
| createFolder("/TestAnnot/src/p2"); |
| createFile( |
| "/TestAnnot/src/p2/Y2.java", |
| "package p2;\n" + |
| "public class Y2{\n" + |
| "}\n" |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_PB_NULL_REFERENCE, JavaCore.ERROR); |
| project15.setOption(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR); |
| project15.setOption(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR); |
| project15.setOption(JavaCore.COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS, JavaCore.ENABLED); |
| project15.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); |
| project15.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR); |
| |
| this.workingCopies = new ICompilationUnit[2]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/TestAnnot/src/p1/Y.java").getWorkingCopy(this.wcOwner, null); |
| this.workingCopies[0].makeConsistent(null); |
| this.workingCopies[0].reconcile(ICompilationUnit.NO_AST, false, null, null); |
| |
| assertNoProblem(sourceChars, this.workingCopies[0]); |
| } finally { |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=374176 |
| // verify that a reconcile DOES result in errors for package-info whose package does not have |
| // default null annotations |
| public void testBug374176b() throws CoreException, IOException, InterruptedException { |
| IJavaProject project15 = null; |
| try { |
| project15 = createJavaProject("TestAnnot", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); |
| createFolder("/TestAnnot/src/p1"); |
| String source = "package p1;\n"; |
| createFile( |
| "/TestAnnot/src/p1/package-info.java", |
| source |
| ); |
| project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); |
| project15.setOption(JavaCore.COMPILER_PB_NULL_REFERENCE, JavaCore.ERROR); |
| project15.setOption(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR); |
| project15.setOption(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR); |
| project15.setOption(JavaCore.COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS, JavaCore.ENABLED); |
| project15.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); |
| project15.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/TestAnnot/src/p1/package-info.java").getWorkingCopy(this.wcOwner, null); |
| this.workingCopies[0].makeConsistent(null); |
| this.workingCopies[0].reconcile(ICompilationUnit.NO_AST, false, null, null); |
| |
| assertProblems("Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /TestAnnot/src/p1/package-info.java (at line 1)\n" + |
| " package p1;\n" + |
| " ^^\n" + |
| "A default nullness annotation has not been specified for the package p1\n" + |
| "----------\n"); |
| assertProblems("Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /TestAnnot/src/p1/package-info.java (at line 1)\n" + |
| " package p1;\n" + |
| " ^^\n" + |
| "A default nullness annotation has not been specified for the package p1\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| if (project15 != null) |
| deleteProject(project15); |
| } |
| } |
| /** |
| * Project's compliance: source: 1.5, compiler: 1.5 |
| * Jar's compliance: source: 1.3, compiler: 1.3 |
| * Jar contains a class with "enum" package and is located inside the project. |
| * The test verifies that class from the "enum" package is correctly reconciled. |
| */ |
| public void testBug410207a() throws Exception { |
| try { |
| IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5"); |
| Util.createJar(new String[] { |
| "a/enum/b/NonCompliant.java", |
| "package a.enum.b;\n" + |
| "public class NonCompliant {\n" + |
| "}", |
| "lib/External.java", |
| "package lib;\n" + |
| "import a.enum.b.NonCompliant;\n" + |
| "public class External {\n" + |
| " public NonCompliant setNonCompliant(NonCompliant x) {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}" |
| }, |
| p.getProject().getLocation().append("lib.jar").toOSString(), |
| "1.3"); |
| refresh(p); |
| setUpWorkingCopy( |
| "/P/src/p/Main.java", |
| "package p;\n" + |
| "import lib.External;\n" + |
| "public class Main {\n" + |
| " public void m() {\n" + |
| " External external = new External();\n" + |
| " external.setNonCompliant(null);\n" + |
| " };\n" + |
| "}" |
| ); |
| this.problemRequestor.reset(); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProject("P"); |
| } |
| } |
| /** |
| * Project's compliance: source: 1.5, compiler: 1.5 |
| * Jar's compliance: source: 1.4, compiler: 1.6 |
| * Jar contains a class with "enum" package and is located inside the project. |
| * The test verifies that class from the "enum" package is correctly reconciled. |
| */ |
| public void testBug410207b() throws Exception { |
| try { |
| IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5"); |
| Map options = new HashMap(); |
| options.put(CompilerOptions.OPTION_Source, "1.4"); |
| Util.createJar(new String[] { |
| "a/enum/b/NonCompliant.java", |
| "package a.enum.b;\n" + |
| "public class NonCompliant {\n" + |
| "}", |
| "lib/External.java", |
| "package lib;\n" + |
| "import a.enum.b.NonCompliant;\n" + |
| "public class External {\n" + |
| " public NonCompliant setNonCompliant(NonCompliant x) {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}" |
| }, |
| null,/*extraPathsAndContents*/ |
| p.getProject().getLocation().append("lib.jar").toOSString(), |
| null,/*classpath*/ |
| "1.6", |
| options); |
| refresh(p); |
| setUpWorkingCopy( |
| "/P/src/p/Main.java", |
| "package p;\n" + |
| "import lib.External;\n" + |
| "public class Main {\n" + |
| " public void m() {\n" + |
| " External external = new External();\n" + |
| " external.setNonCompliant(null);\n" + |
| " };\n" + |
| "}" |
| ); |
| this.problemRequestor.reset(); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProject("P"); |
| } |
| } |
| /** |
| * Two projects: |
| * Lib: source: 1.4, compiler: 1.4 |
| * P: source: 1.5, compiler: 1.5 |
| * Lib contains a class with "enum" package and is required by P (dependency on the bin folder). |
| * The test verifies that class from the "enum" package is correctly reconciled for P. |
| */ |
| public void testBug410207c() throws Exception { |
| try { |
| createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4"); |
| createFolder("/Lib/src/a/enum/b"); |
| createFile( |
| "/Lib/src/a/enum/b/NonCompliant.java", |
| "package a.enum.b;\n" + |
| "public class NonCompliant {\n" + |
| "}" |
| ); |
| createFolder("/Lib/src/lib"); |
| createFile( |
| "/Lib/src/lib/External.java", |
| "package lib;\n" + |
| "import a.enum.b.NonCompliant;\n" + |
| "public class External {\n" + |
| " public NonCompliant setNonCompliant(NonCompliant x) {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}" |
| ); |
| getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null); |
| createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/Lib/bin"}, "bin", "1.5"); |
| setUpWorkingCopy( |
| "/P/src/p/Main.java", |
| "package p;\n" + |
| "import lib.External;\n" + |
| "public class Main {\n" + |
| " public void m() {\n" + |
| " External external = new External();\n" + |
| " external.setNonCompliant(null);\n" + |
| " };\n" + |
| "}" |
| ); |
| this.problemRequestor.reset(); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProjects(new String[] { "Lib", "P" }); |
| } |
| } |
| /** |
| * Two projects: |
| * Lib: source: 1.4, compiler: 1.4 |
| * P: source: 1.5, compiler: 1.5 |
| * Lib contains a class with "enum" package and is required by P (dependency on the whole project). |
| * The test verifies that class from the "enum" package is correctly reconciled for P. |
| */ |
| public void testBug410207d() throws Exception { |
| try { |
| createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4"); |
| createFolder("/Lib/src/a/enum/b"); |
| createFile( |
| "/Lib/src/a/enum/b/NonCompliant.java", |
| "package a.enum.b;\n" + |
| "public class NonCompliant {\n" + |
| "}" |
| ); |
| createFolder("/Lib/src/lib"); |
| createFile( |
| "/Lib/src/lib/External.java", |
| "package lib;\n" + |
| "import a.enum.b.NonCompliant;\n" + |
| "public class External {\n" + |
| " public NonCompliant setNonCompliant(NonCompliant x) {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}" |
| ); |
| getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null); |
| createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, new String[] {"/Lib"}, "bin", "1.5"); |
| setUpWorkingCopy( |
| "/P/src/p/Main.java", |
| "package p;\n" + |
| "import lib.External;\n" + |
| "public class Main {\n" + |
| " public void m() {\n" + |
| " External external = new External();\n" + |
| " external.setNonCompliant(null);\n" + |
| " };\n" + |
| "}" |
| ); |
| this.problemRequestor.reset(); |
| this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n" |
| ); |
| } finally { |
| deleteProjects(new String[] { "Lib", "P" }); |
| } |
| } |
| } |