/******************************************************************************* * Copyright (c) 2000, 2015 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 * Stephan Herrmann - Contribution for * bug 401035 - [1.8] A few tests have started failing recently *******************************************************************************/ 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.FileLocator; 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; import org.osgi.framework.Bundle; @SuppressWarnings({"rawtypes", "unchecked"}) 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); } } /*package*/ static final int JLS_LATEST = AST.JLS8; 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.getAST8(); } 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.getAST8(); 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.getAST8(); 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(JLS_LATEST, 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); } protected 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 API (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 API (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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, true/*force problem detection*/, null/*primary owner*/, monitor); setWorkingCopyContents( "package p1;\n" + "import p2.*;\n" + "public class X {\n" + "}"); ReconcilerTests.this.workingCopy.reconcile(JLS_LATEST, 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(JLS_LATEST, 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 correctly 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 API (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 API (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 API (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 API (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 API (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", "[Working copy] X.java[*]: {CONTENT | FINE GRAINED}" ); 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", "[Working copy] X.java[*]: {CONTENT | FINE GRAINED}" ); 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" ); } /** * Introduces a syntax error in the modifiers of a method. * Variant to force the expected modifier change. */ public void testMethodWithError01a() 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 \"public_\", public expected\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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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( JLS_LATEST, 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( JLS_LATEST, 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); } } public void testSecondaryTypeDeletion() throws CoreException, IOException { // Set working copy content with no error setUpWorkingCopy("/Reconciler/src/X.java", "interface I {\n" + " void foo();\n" + "}\n" + "public class X {\n" + " static void goo(I i) {\n" + " }\n" + "}\n" ); assertProblems( "Unexpected problems", "----------\n" + "----------\n" ); String contents = "public class X {\n" + " static void goo(I i) {\n" + " }\n" + "}\n"; setWorkingCopyContents(contents); this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null); assertProblems( "Wrong expected problems", "----------\n" + "1. ERROR in /Reconciler/src/X.java (at line 2)\n" + " static void goo(I i) {\n" + " ^\n" + "I cannot be resolved to a type\n" + "----------\n" ); } /** * 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" }); } } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=440592, Cannot easily launch application in case of certain usage of lambda expressions public void testBug440592() throws Exception { try { createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_FULL"}, "bin", "1.8", true); createFile( "/P/src/BugTest.java", "public class BugTest {\n" + " public void baz(InterfaceForBugTest arg) {\n" + " }\n" + " public void bar() {\n" + " baz(InterfaceForBugTest.instance); \n" + " }\n" + " public Runnable returningLambda() { \n" + " return () -> {\n" + " };\n" + " }\n" + " public static void main(String[] args) {\n" + " }\n" + "}\n" ); createFile( "/P/src/InterfaceForBugTest.java", "public interface InterfaceForBugTest {\n" + " public static InterfaceForBugTest creator1(Runnable simpleInstance){\n" + " return null;\n" + " }\n" + " public static void methodWithAnonymousImplementation() {\n" + " new InterfaceForBugTest() {\n" + " @Override\n" + " public void fun1() {\n" + " }\n" + " @Override\n" + " public void fun2() {\n" + " }\n" + " @Override\n" + " public void fun3() {\n" + " }\n" + " @Override\n" + " public void fun4() {\n" + " }\n" + " @Override\n" + " public void fun5() {\n" + " }\n" + " };\n" + " } \n" + " public static void methodWithAnonymousImplementation2() {\n" + " new InterfaceForBugTest() {\n" + " @Override\n" + " public void fun1() {\n" + " }\n" + " @Override\n" + " public void fun2() {\n" + " }\n" + " @Override\n" + " public void fun3() {\n" + " }\n" + " @Override\n" + " public void fun4() {\n" + " }\n" + " @Override\n" + " public void fun5() {\n" + " }\n" + " };\n" + " }\n" + " public static InterfaceForBugTest instance = creator1(() -> {\n" + " });\n" + " void fun1();\n" + " void fun2();\n" + " void fun3();\n" + " void fun4();\n" + " void fun5();\n" + "}\n" ); getProject("P").build(IncrementalProjectBuilder.FULL_BUILD, null); setUpWorkingCopy( "/P/src/BugTest.java", "public class BugTest {\n" + " public void baz(InterfaceForBugTest arg) {\n" + " }\n" + " public void bar() {\n" + " baz(InterfaceForBugTest.instance); \n" + " }\n" + " public Runnable returningLambda() { \n" + " return () -> {\n" + " };\n" + " }\n" + " public static void main(String[] args) {\n" + " }\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[] { "P" }); } } public void testBug485092() throws CoreException, IOException, InterruptedException { IJavaProject project15 = null; IJavaProject project18 = null; try { project15 = createJavaProject("Reconciler1518", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); createFolder("/Reconciler1518/src/p1"); String source = "package p1;\n" + "\n" + "public interface PreferenceableOption<T extends Object> {}\n"; createFile( "/Reconciler1518/src/p1/PreferenceableOption.java", source ); 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); project18 = createJavaProject("Reconciler18", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); createFolder("/Reconciler18/src/p2"); String otherSource = "package p2;\n" + "import org.eclipse.jdt.annotation.NonNull;\n" + "import org.eclipse.jdt.annotation.Nullable;\n" + "\n" + "import p1.PreferenceableOption;\n" + "public class PivotEnvironmentFactory\n" + "{\n" + " public @NonNull Object @Nullable [] scopeContexts = null;\n" + "}\n"; createFile( "/Reconciler18/src/p2/PivotEnvironmentFactory.java", otherSource ); project18.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8); project18.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8); project18.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8); project18.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); Bundle[] bundles = Platform.getBundles("org.eclipse.jdt.annotation","[2.0.0,3.0.0)"); File bundleFile = FileLocator.getBundleFile(bundles[0]); String annotationsLib = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath(); IClasspathEntry nullAnnotationsClassPathEntry = JavaCore.newLibraryEntry(new Path(annotationsLib), null, null); IClasspathEntry[] oldClasspath = project18.getRawClasspath(); int oldLength = oldClasspath.length; IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+2]; System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler1518")); newClasspath[oldLength + 1] = nullAnnotationsClassPathEntry; project18.setRawClasspath(newClasspath, null); this.workingCopies = new ICompilationUnit[1]; char[] sourceChars = otherSource.toCharArray(); this.problemRequestor.initialize(sourceChars); this.workingCopies[0] = getCompilationUnit("/Reconciler18/src/p2/PivotEnvironmentFactory.java").getWorkingCopy(this.wcOwner, null); assertProblems( "Unexpected problems", "----------\n" + "1. WARNING in /Reconciler18/src/p2/PivotEnvironmentFactory.java (at line 5)\n" + " import p1.PreferenceableOption;\n" + " ^^^^^^^^^^^^^^^^^^^^^^^\n" + "The import p1.PreferenceableOption is never used\n" + "----------\n" ); } finally { if (project15 != null) deleteProject(project15); if (project18 != null) deleteProject(project18); } } }