diff --git a/docs/Getting-Started-with-Groovy-Eclipse-Source-Code.md b/docs/Getting-Started-with-Groovy-Eclipse-Source-Code.md
index 2835ec241c..e6893f0c7e 100644
--- a/docs/Getting-Started-with-Groovy-Eclipse-Source-Code.md
+++ b/docs/Getting-Started-with-Groovy-Eclipse-Source-Code.md
@@ -190,6 +190,7 @@ Replace e47 with a different option to build it for another Eclipse version:
* e48
* e49
* e4.10
+* e4.11
Tests will be executed as part of the build. To skip them, append this option to the command: `-Dmaven.test.skip=true`.
diff --git a/groovy-eclipse.setup b/groovy-eclipse.setup
index 418afe8d60..6f0e10b9e3 100644
--- a/groovy-eclipse.setup
+++ b/groovy-eclipse.setup
@@ -72,6 +72,9 @@
defaultValue="Oxygen"
storageURI="scope://Workspace"
label="Target Platform">
+
@@ -122,7 +125,15 @@
+ filter="(| (scope.product.version.name=2019-03) (scope.product.version.name=latest))">
+
+
+
+
+
+
+
@@ -250,6 +268,13 @@
name="org.eclipse.m2e.sdk.feature.feature.group"/>
+
+
+
+
+
+ Feature-org.codehaus.groovy.jdt.patch
+
+
+ org.eclipse.pde.FeatureBuilder
+
+
+
+ org.eclipse.pde.FeatureNature
+
+
diff --git a/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/build.properties b/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/build.properties
new file mode 100644
index 0000000000..964061ffe0
--- /dev/null
+++ b/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/build.properties
@@ -0,0 +1,7 @@
+bin.includes = feature.properties,\
+ feature.xml,\
+ license.html
+src.includes = build.properties,\
+ feature.properties,\
+ feature.xml,\
+ license.html
diff --git a/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/feature.properties b/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/feature.properties
new file mode 100644
index 0000000000..7b4f8f2827
--- /dev/null
+++ b/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/feature.properties
@@ -0,0 +1,124 @@
+# contains externalized strings for feature.xml
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+
+providerName=Pivotal Software, Inc.
+
+featureName=Eclipse JDT Core patch for Groovy
+
+descriptionURL=https://github.com/groovy/groovy-eclipse/wiki
+
+description=This JDT Core patch provides Groovy integration with the JDT and the Java compiler.
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2009-2019 Pivotal Software, Inc. and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
diff --git a/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/feature.xml b/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/feature.xml
new file mode 100644
index 0000000000..056fa6d4b9
--- /dev/null
+++ b/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/feature.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+ %description
+
+
+
+ %copyright
+
+
+
+ %license
+
+
+
+
+
+
+
+
+
diff --git a/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/license.html b/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/license.html
new file mode 100644
index 0000000000..71b4d05e59
--- /dev/null
+++ b/jdt-patch/e411/Feature-org.codehaus.groovy.jdt.patch/license.html
@@ -0,0 +1,109 @@
+
+
+
+
+Eclipse.org Software User Agreement
+
Eclipse Foundation Software User Agreement
+
March 17, 2005
+
+
Usage Of Content
+
+
THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+ (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+ CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+ OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+ NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+ CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.
+
+
Applicable Licenses
+
+
Unless otherwise indicated, all Content made available by the
+Eclipse Foundation is provided to you under the terms and conditions of
+the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is
+provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html.
+ For purposes of the EPL, "Program" will mean the Content.
+
+
Content includes, but is not limited to, source code, object code,
+documentation and other files maintained in the Eclipse.org CVS
+repository ("Repository") in CVS modules ("Modules") and made available
+as downloadable archives ("Downloads").
+
+
+
Content may be structured and packaged into modules to
+facilitate delivering, extending, and upgrading the Content. Typical
+modules may include plug-ins ("Plug-ins"), plug-in fragments
+("Fragments"), and features ("Features").
+
Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
+
A
+Feature is a bundle of one or more Plug-ins and/or Fragments and
+associated material. Each Feature may be packaged as a sub-directory in
+a directory named "features". Within a Feature, files named
+"feature.xml" may contain a list of the names and version numbers of
+the Plug-ins and/or Fragments associated with that Feature.
+
Features
+may also include other Features ("Included Features"). Within a
+Feature, files named "feature.xml" may contain a list of the names and
+version numbers of Included Features.
+
+
+
The terms and conditions governing Plug-ins and Fragments should be
+contained in files named "about.html" ("Abouts"). The terms and
+conditions governing Features and
+Included Features should be contained in files named "license.html"
+("Feature Licenses"). Abouts and Feature Licenses may be located in any
+directory of a Download or Module
+including, but not limited to the following locations:
+
+
+
The top-level (root) directory
+
Plug-in and Fragment directories
+
Inside Plug-ins and Fragments packaged as JARs
+
Sub-directories of the directory named "src" of certain Plug-ins
+
Feature directories
+
+
+
Note: if a Feature made available by the Eclipse Foundation is
+installed using the Eclipse Update Manager, you must agree to a license
+("Feature Update License") during the
+installation process. If the Feature contains Included Features, the
+Feature Update License should either provide you with the terms and
+conditions governing the Included Features or
+inform you where you can locate them. Feature Update Licenses may be
+found in the "license" property of files named "feature.properties"
+found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the
+terms and conditions (or references to such terms and conditions) that
+govern your use of the associated Content in
+that directory.
+
+
THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND
+CONDITIONS. SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):
IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND
+CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License,
+or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions
+govern that particular Content.
+
+
Cryptography
+
+
Content may contain encryption software. The country in which you
+are currently may have restrictions on the import, possession, and use,
+and/or re-export to another country, of encryption software. BEFORE
+using any encryption software, please check the country's laws,
+regulations and policies concerning the import, possession, or use, and
+re-export of encryption software, to see if this is permitted.
+ The Eclipse Foundation makes available all content in this plug-in
+ ("Content"). Unless otherwise indicated below, the Content
+ is provided to you under the terms and conditions of the Eclipse
+ Public License Version 2.0 ("EPL"). A copy of the EPL is
+ available at http://www.eclipse.org/legal/epl-2.0.
+ For purposes of the EPL, "Program" will mean the Content.
+
+
+
+ If you did not receive this Content directly from the Eclipse
+ Foundation, the Content is being redistributed by another party
+ ("Redistributor") and different terms and conditions may
+ apply to your use of any object code in the Content. Check the
+ Redistributor's license that was provided with the Content. If no such
+ license exists, contact the Redistributor. Unless otherwise indicated
+ below, the terms and conditions of the EPL still apply to any source
+ code in the Content and such source code may be obtained at http://www.eclipse.org.
+
+
+
+
\ No newline at end of file
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/build.properties b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/build.properties
new file mode 100644
index 0000000000..94b8ae8fe0
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/build.properties
@@ -0,0 +1,23 @@
+###############################################################################
+# Copyright (c) 2000, 2013 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+# Red Hat Inc. (mistria) - Avoid nested jars
+###############################################################################
+bin.includes = plugin.xml,\
+ test.xml,\
+ about.html,\
+ .,\
+ META-INF/,\
+ plugin.properties
+source.. = src/
+output.. = bin/
+src.includes=about.html
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/forceQualifierUpdate.txt b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/forceQualifierUpdate.txt
new file mode 100644
index 0000000000..073841225f
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/forceQualifierUpdate.txt
@@ -0,0 +1,2 @@
+# To force a version qualifier update, add the bug here
+Bug 480835 - Failures in build due to changes not being picked up by tests
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/plugin.properties b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/plugin.properties
new file mode 100644
index 0000000000..67609b5a82
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/plugin.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2000, 2006 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+providerName=Eclipse.org
+pluginName=Java Builder Tests
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/plugin.xml b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/plugin.xml
new file mode 100644
index 0000000000..a2cf6324a2
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/plugin.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/pom.xml b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/pom.xml
new file mode 100644
index 0000000000..4db2ac3567
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/pom.xml
@@ -0,0 +1,24 @@
+
+
+
+ 4.0.0
+
+ eclipse.jdt.core
+ tests-pom
+ 4.11.0-SNAPSHOT
+ ../tests-pom/
+
+ org.eclipse.jdt
+ org.eclipse.jdt.core.tests.builder
+ 3.10.400-SNAPSHOT
+ eclipse-plugin
+
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AbstractMethodTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AbstractMethodTests.java
new file mode 100644
index 0000000000..2610aa75d8
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AbstractMethodTests.java
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import junit.framework.*;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IRegion;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.core.util.IClassFileReader;
+import org.eclipse.jdt.core.util.IMethodInfo;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class AbstractMethodTests extends BuilderTests {
+ private static final Comparator COMPARATOR = new Comparator() {
+ public int compare(Object o1, Object o2) {
+ IResource resource1 = (IResource) o1;
+ IResource resource2 = (IResource) o2;
+ String path1 = resource1.getFullPath().toString();
+ String path2 = resource2.getFullPath().toString();
+ int length1 = path1.length();
+ int length2 = path2.length();
+
+ if (length1 != length2) {
+ return length1 - length2;
+ }
+ return path1.toString().compareTo(path2.toString());
+ }
+ };
+
+ public AbstractMethodTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(AbstractMethodTests.class);
+ }
+
+ /**
+ * Check behavior in 1.2 target mode (NO generated default abstract method)
+ */
+ public void test001() throws JavaModelException {
+ //----------------------------
+ // Step 1
+ //----------------------------
+ //----------------------------
+ // Project1
+ //----------------------------
+ IPath project1Path = env.addProject("Project1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(project1Path, ""); //$NON-NLS-1$
+
+ env.setOutputFolder(project1Path, "bin"); //$NON-NLS-1$
+ IPath root1 = env.addPackageFragmentRoot(project1Path, "src"); //$NON-NLS-1$
+
+ env.addClass(root1, "p1", "IX", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n" + //$NON-NLS-1$
+ "public interface IX {\n" + //$NON-NLS-1$
+ " public abstract void foo(IX x);\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath classX = env.addClass(root1, "p2", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n" + //$NON-NLS-1$
+ "import p1.*;\n" + //$NON-NLS-1$
+ "public abstract class X implements IX {\n" + //$NON-NLS-1$
+ " public void foo(IX x){}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ //----------------------------
+ // Project2
+ //----------------------------
+ IPath project2Path = env.addProject("Project2"); //$NON-NLS-1$
+ env.addExternalJars(project2Path, Util.getJavaClassLibs());
+ env.addRequiredProject(project2Path, project1Path);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(project2Path, ""); //$NON-NLS-1$
+
+ IPath root2 = env.addPackageFragmentRoot(project2Path, "src"); //$NON-NLS-1$
+ env.setOutputFolder(project2Path, "bin"); //$NON-NLS-1$
+
+ IPath classY =env.addClass(root2, "p3", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n" + //$NON-NLS-1$
+ "import p2.*;\n" + //$NON-NLS-1$
+ "public class Y extends X{\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingNoProblems();
+
+ //----------------------------
+ // Step 2
+ //----------------------------
+ env.addClass(root1, "p2", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n" + //$NON-NLS-1$
+ "import p1.*;\n" + //$NON-NLS-1$
+ "public abstract class X implements IX {\n" + //$NON-NLS-1$
+ " public void foo(I__X x){}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ expectingOnlySpecificProblemFor(classX, new Problem("X.foo(I__X)", "I__X cannot be resolved to a type", classX, 84, 88, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingOnlySpecificProblemFor(classY, new Problem("Y", "The type Y must implement the inherited abstract method IX.foo(IX)", classY, 38, 39, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ //----------------------------
+ // Step 3
+ //----------------------------
+ env.addClass(root1, "p2", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n" + //$NON-NLS-1$
+ "import p1.*;\n" + //$NON-NLS-1$
+ "public abstract class X implements IX {\n" + //$NON-NLS-1$
+ " public void foo(IX x){}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ expectingNoProblems();
+ }
+
+ /**
+ * Check behavior in 1.1 target mode (generated default abstract method)
+ */
+ public void test002() throws JavaModelException {
+ //----------------------------
+ // Step 1
+ //----------------------------
+ //----------------------------
+ // Project1
+ //----------------------------
+ IPath project1Path = env.addProject("Project1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+ env.getJavaProject(project1Path).setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_1); // need default abstract method
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(project1Path, ""); //$NON-NLS-1$
+
+ env.setOutputFolder(project1Path, "bin"); //$NON-NLS-1$
+ IPath root1 = env.addPackageFragmentRoot(project1Path, "src"); //$NON-NLS-1$
+
+ env.addClass(root1, "p1", "IX", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n" + //$NON-NLS-1$
+ "public interface IX {\n" + //$NON-NLS-1$
+ " public abstract void foo(IX x);\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath classX = env.addClass(root1, "p2", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n" + //$NON-NLS-1$
+ "import p1.*;\n" + //$NON-NLS-1$
+ "public abstract class X implements IX {\n" + //$NON-NLS-1$
+ " public void foo(IX x){}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ //----------------------------
+ // Project2
+ //----------------------------
+ IPath project2Path = env.addProject("Project2"); //$NON-NLS-1$
+ env.addExternalJars(project2Path, Util.getJavaClassLibs());
+ env.addRequiredProject(project2Path, project1Path);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(project2Path, ""); //$NON-NLS-1$
+
+ IPath root2 = env.addPackageFragmentRoot(project2Path, "src"); //$NON-NLS-1$
+ env.setOutputFolder(project2Path, "bin"); //$NON-NLS-1$
+
+ IPath classY =env.addClass(root2, "p3", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n" + //$NON-NLS-1$
+ "import p2.*;\n" + //$NON-NLS-1$
+ "public class Y extends X{\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingNoProblems();
+
+ //----------------------------
+ // Step 2
+ //----------------------------
+ env.addClass(root1, "p2", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n" + //$NON-NLS-1$
+ "import p1.*;\n" + //$NON-NLS-1$
+ "public abstract class X implements IX {\n" + //$NON-NLS-1$
+ " public void foo(I__X x){}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ expectingOnlySpecificProblemFor(classX, new Problem("X.foo(I__X)", "I__X cannot be resolved to a type", classX, 84, 88, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingOnlySpecificProblemFor(classY, new Problem("Y", "The type Y must implement the inherited abstract method IX.foo(IX)", classY, 38, 39, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ //----------------------------
+ // Step 3
+ //----------------------------
+ env.addClass(root1, "p2", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n" + //$NON-NLS-1$
+ "import p1.*;\n" + //$NON-NLS-1$
+ "public abstract class X implements IX {\n" + //$NON-NLS-1$
+ " public void foo(IX x){}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ expectingNoProblems();
+ }
+
+ /**
+ * Check behavior in 1.1 target mode (generated default abstract method)
+ */
+ public void test003() throws JavaModelException {
+ //----------------------------
+ // Step 1
+ //----------------------------
+ //----------------------------
+ // Project1
+ //----------------------------
+ IPath project1Path = env.addProject("Project1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+ env.getJavaProject(project1Path).setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_1); // need default abstract method
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(project1Path, ""); //$NON-NLS-1$
+
+ env.setOutputFolder(project1Path, "bin"); //$NON-NLS-1$
+ IPath root1 = env.addPackageFragmentRoot(project1Path, "src"); //$NON-NLS-1$
+
+ env.addClass(root1, "p1", "IX", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n" + //$NON-NLS-1$
+ "public interface IX {\n" + //$NON-NLS-1$
+ " public abstract void foo(IX x);\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root1, "p2", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n" + //$NON-NLS-1$
+ "import p1.*;\n" + //$NON-NLS-1$
+ "public abstract class X implements IX {\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingNoProblems();
+
+ IJavaProject project = env.getJavaProject(project1Path);
+ IRegion region = JavaCore.newRegion();
+ region.add(project);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput = "/Project1/bin/p2/X.class\n" +
+ "/Project1/bin/p1/IX.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ assertEquals("Wrong type", IResource.FILE, resources[0].getType());
+ IFile classFile = (IFile) resources[0];
+ IClassFileReader classFileReader = null;
+ InputStream stream = null;
+ try {
+ stream = classFile.getContents();
+ classFileReader = ToolFactory.createDefaultClassFileReader(stream, IClassFileReader.ALL);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch(IOException e) {
+ // ignore
+ }
+ }
+ }
+ assertNotNull("No class file reader", classFileReader);
+ IMethodInfo[] methodInfos = classFileReader.getMethodInfos();
+ IMethodInfo found = null;
+ loop: for (int i = 0, max = methodInfos.length; i < max; i++) {
+ IMethodInfo methodInfo = methodInfos[i];
+ if (CharOperation.equals(methodInfo.getName(), "foo".toCharArray())) {
+ found = methodInfo;
+ break loop;
+ }
+ }
+ assertNotNull("No method found", found);
+ assertTrue("Not a synthetic method", found.isSynthetic());
+ }
+
+ private String getResourceOuput(IResource[] resources) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter writer = new PrintWriter(stringWriter);
+ for (int i = 0, max = resources.length; i < max; i++) {
+ writer.println(resources[i].getFullPath().toString());
+ }
+ writer.flush();
+ writer.close();
+ return Util.convertToIndependantLineDelimiter(String.valueOf(stringWriter));
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java
new file mode 100644
index 0000000000..6455f2531f
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java
@@ -0,0 +1,1672 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2014 Walter Harley and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Walter Harley (eclipse@cafewalter.com) - initial implementation
+ * IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contributions for
+ * bug 365992 - [builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method
+ * Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Test;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.osgi.framework.Bundle;
+
+/**
+ * Tests to verify that annotation changes cause recompilation of dependent types.
+ * See http://bugs.eclipse.org/149768
+ */
+public class AnnotationDependencyTests extends BuilderTests {
+ private IPath srcRoot = null;
+ private IPath projectPath = null;
+
+ public AnnotationDependencyTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(AnnotationDependencyTests.class);
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+
+ this.projectPath = env.addProject("Project", "1.5"); //$NON-NLS-1$
+ env.addExternalJars(this.projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(this.projectPath,""); //$NON-NLS-1$
+
+ this.srcRoot = env.addPackageFragmentRoot(this.projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(this.projectPath, "bin"); //$NON-NLS-1$
+ }
+
+ protected void tearDown() throws Exception {
+ this.projectPath = null;
+ this.srcRoot = null;
+
+ super.tearDown();
+ }
+
+ private void addAnnotationType() {
+ String annoCode = "package p1;\n"
+ + "@interface Anno {\n"
+ + "String value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "Anno", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoInt {\n"
+ + "int value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoInt", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoBoolean {\n"
+ + "boolean value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoBoolean", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoByte {\n"
+ + "byte value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoByte", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoChar {\n"
+ + "char value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoChar", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoShort {\n"
+ + "short value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoShort", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoDouble {\n"
+ + "double value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoDouble", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoFloat {\n"
+ + "float value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoFloat", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoLong {\n"
+ + "long value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoLong", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoStringArray {\n"
+ + "String[] value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoStringArray", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoAnnotation {\n"
+ + "AnnoLong value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoAnnotation", annoCode);
+ annoCode = "package p1;\n"
+ + "enum E {\n"
+ + "A, B, C\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "E", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoEnum {\n"
+ + "E value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoEnum", annoCode);
+ annoCode = "package p1;\n"
+ + "@interface AnnoClass {\n"
+ + "Class> value();\n"
+ + "}\n";
+ env.addClass(this.srcRoot, "p1", "AnnoClass", annoCode);
+ }
+
+ void setupProjectForNullAnnotations() throws IOException, JavaModelException {
+ // add the org.eclipse.jdt.annotation library (bin/ folder or jar) to the project:
+ Bundle[] bundles = Platform.getBundles("org.eclipse.jdt.annotation","[1.1.0,2.0.0)");
+ File bundleFile = FileLocator.getBundleFile(bundles[0]);
+ String annotationsLib = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath();
+ IJavaProject javaProject = env.getJavaProject(this.projectPath);
+ IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
+ int len = rawClasspath.length;
+ System.arraycopy(rawClasspath, 0, rawClasspath = new IClasspathEntry[len+1], 0, len);
+ rawClasspath[len] = JavaCore.newLibraryEntry(new Path(annotationsLib), null, null);
+ javaProject.setRawClasspath(rawClasspath, null);
+
+ javaProject.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
+ }
+
+ /**
+ * This test makes sure that changing an annotation on type A causes type B
+ * to be recompiled, if B references A. See http://bugs.eclipse.org/149768
+ */
+ public void testTypeAnnotationDependency() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@Anno(\"A1\")" + "\n"
+ + "public class A {}";
+ String a2Code = "package p1; " + "\n"
+ + "@Anno(\"A2\")" + "\n"
+ + "public class A {}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+
+ /**
+ * This test makes sure that changing an annotation on a field within type A
+ * causes type B to be recompiled, if B references A.
+ * See http://bugs.eclipse.org/149768
+ */
+ public void testFieldAnnotationDependency() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "public class A {" + "\n"
+ + " @Anno(\"A1\")" + "\n"
+ + " protected int f;" + "\n"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "public class A {" + "\n"
+ + " @Anno(\"A2\")" + "\n"
+ + " protected int f;" + "\n"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+
+ /**
+ * This test makes sure that changing an annotation on a method within type A
+ * causes type B to be recompiled, if B references A.
+ * See http://bugs.eclipse.org/149768
+ */
+ public void testMethodAnnotationDependency() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "public class A {" + "\n"
+ + " @Anno(\"A1\")" + "\n"
+ + " protected int f() { return 0; }" + "\n"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "public class A {" + "\n"
+ + " @Anno(\"A2\")" + "\n"
+ + " protected int f() { return 0; }" + "\n"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+
+ /**
+ * This test makes sure that changing an annotation on an inner type X within type A
+ * causes type B to be recompiled, if B references A.
+ * Note that B does not directly reference A.X, only A.
+ * See http://bugs.eclipse.org/149768
+ */
+ public void testInnerTypeAnnotationDependency() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "public class A {" + "\n"
+ + " @Anno(\"A1\")" + "\n"
+ + " public class X { }" + "\n"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "public class A {" + "\n"
+ + " @Anno(\"A2\")" + "\n"
+ + " public class X { }" + "\n"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.A$X", "p1.B" });
+ }
+
+ /**
+ * This test makes sure that changing an annotation on a type A
+ * does not cause type B to be recompiled, if B does not reference A.
+ * See http://bugs.eclipse.org/149768
+ */
+ public void testUnrelatedTypeAnnotationDependency() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@Anno(\"A1\")" + "\n"
+ + "public class A {}";
+ String a2Code = "package p1; " + "\n"
+ + "@Anno(\"A2\")" + "\n"
+ + "public class A {}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was not recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=214948
+ public void testPackageInfoDependency() throws Exception {
+ String notypes = "@question.SimpleAnnotation(\"foo\") package notypes;";
+ String question = "package question;";
+ String deprecatedQuestion = "@Deprecated package question;";
+ String SimpleAnnotation = "package question; " + "\n"
+ + "public @interface SimpleAnnotation { String value(); }";
+
+ IPath notypesPath = env.addClass( this.srcRoot, "notypes", "package-info", notypes );
+ env.addClass( this.srcRoot, "question", "package-info", question );
+ env.addClass( this.srcRoot, "question", "SimpleAnnotation", SimpleAnnotation );
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ env.addClass( this.srcRoot, "question", "package-info", deprecatedQuestion );
+ incrementalBuild( this.projectPath );
+ expectingOnlySpecificProblemFor(notypesPath, new Problem("", "The type SimpleAnnotation is deprecated", notypesPath, 10, 26, CategorizedProblem.CAT_DEPRECATION, IMarker.SEVERITY_WARNING)); //$NON-NLS-1$
+
+ env.addClass( this.srcRoot, "question", "package-info", question );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency2() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@Anno(\"A1\")" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@Anno(\"A1\")" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency3() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoInt(24)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoInt(24)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency4() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoByte(3)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoByte(3)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency5() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoBoolean(true)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoBoolean(true)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency6() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoChar('c')" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoChar('c')" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency7() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoDouble(1.0)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoDouble(1.0)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency8() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoFloat(1.0f)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoFloat(1.0f)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency9() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoLong(1L)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoLong(1L)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency10() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoShort(3)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoShort(3)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency11() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoStringArray({\"A1\",\"A2\"})" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoStringArray({\"A1\",\"A2\"})" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency12() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoAnnotation(@AnnoLong(3))" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoAnnotation(@AnnoLong(3))" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency13() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoEnum(E.A)\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoEnum(E.A)\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency14() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoClass(Object.class)\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoClass(Object.class)\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was NOT recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency15() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@Anno(\"A1\")" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@Anno(\"A2\")" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency16() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoInt(3)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoInt(4)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency17() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoByte(3)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoByte(4)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B"});
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency18() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoBoolean(true)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoBoolean(false)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency19() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoChar('c')" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoChar('d')" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency20() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoDouble(1.0)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoDouble(2.0)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency21() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoFloat(1.0f)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoFloat(2.0f)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency22() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoLong(1L)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoLong(2L)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency23() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoShort(3)" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoShort(5)" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency24() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoStringArray({\"A1\",\"A2\"})" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoStringArray({\"A2\",\"A1\"})" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency25() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoAnnotation(@AnnoLong(3))" + "\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoAnnotation(@AnnoLong(4))" + "\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency26() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoEnum(E.A)\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoEnum(E.C)\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841
+ */
+ public void testTypeAnnotationDependency27() throws Exception
+ {
+ String a1Code = "package p1; " + "\n"
+ + "@AnnoClass(Object.class)\n"
+ + "public class A {\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String a2Code = "package p1; " + "\n"
+ + "@AnnoClass(String.class)\n"
+ + "public class A {\n"
+ + "\n"
+ + " public void foo() {\n"
+ + " System.out.println(\"test\");"
+ + " }"
+ + "}";
+ String bCode = "package p1; " + "\n"
+ + "public class B {" + "\n"
+ + " public A a;" + "\n"
+ + "}";
+
+ env.addClass( this.srcRoot, "p1", "A", a1Code );
+ env.addClass( this.srcRoot, "p1", "B", bCode );
+ addAnnotationType();
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit annotation in A
+ env.addClass( this.srcRoot, "p1", "A", a2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that B was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" });
+ }
+
+ // Bug 365992 - [builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method
+ public void testParameterAnnotationDependency01() throws JavaModelException, IOException {
+ // prepare the project:
+ setupProjectForNullAnnotations();
+
+ String test1Code = "package p1;\n" +
+ "public class Test1 {\n" +
+ " public void foo() {\n" +
+ " new Test2().bar(null);\n" +
+ " }\n" +
+ "}";
+ String test2Code = "package p1;\n" +
+ "public class Test2 {\n" +
+ " public void bar(String str) {}\n" +
+ "}";
+
+ IPath test1Path = env.addClass( this.srcRoot, "p1", "Test1", test1Code );
+ env.addClass( this.srcRoot, "p1", "Test2", test2Code );
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit Test2 to add @NonNull annotation (changes number of annotations)
+ String test2CodeB = "package p1;\n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "public class Test2 {\n" +
+ " public void bar(@NonNull String str) {}\n" +
+ "}";
+ env.addClass( this.srcRoot, "p1", "Test2", test2CodeB );
+ incrementalBuild( this.projectPath );
+ expectingProblemsFor(test1Path,
+ "Problem : Null type mismatch: required \'@NonNull String\' but the provided value is null [ resource : range : <81,85> category : <90> severity : <2>]");
+
+ // verify that Test1 was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test2" });
+
+ // fix error by changing to @Nullable (change is only in an annotation name)
+ String test2CodeC = "package p1;\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "public class Test2 {\n" +
+ " public void bar(@Nullable String str) {}\n" +
+ "}";
+ env.addClass( this.srcRoot, "p1", "Test2", test2CodeC );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that Test1 was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test2" });
+ }
+
+ // Bug 365992 - [builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method
+ // Bug 366341 - Incremental compiler fails to detect right scope for annotation related code changes
+ public void testReturnAnnotationDependency01() throws JavaModelException, IOException {
+ // prepare the project:
+ setupProjectForNullAnnotations();
+
+ String test1Code = "package p1;\n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "public class Test1 {\n" +
+ " public @NonNull Object foo() {\n" +
+ " return new Test2().bar();\n" +
+ " }\n" +
+ "}";
+ String test2Code = "package p1;\n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "public class Test2 {\n" +
+ " public @NonNull Object bar() { return this; }\n" +
+ "}";
+
+ IPath test1Path = env.addClass( this.srcRoot, "p1", "Test1", test1Code );
+ env.addClass( this.srcRoot, "p1", "Test2", test2Code );
+
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // edit Test2 to replace annotation
+ String test2CodeB = "package p1;\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "public class Test2 {\n" +
+ " public @Nullable Object bar() { return null; }\n" +
+ "}";
+ env.addClass( this.srcRoot, "p1", "Test2", test2CodeB );
+ incrementalBuild( this.projectPath );
+ expectingProblemsFor(test1Path,
+ "Problem : Null type mismatch: required \'@NonNull Object\' but the provided value is specified as @Nullable [ resource : range : <126,143> category : <90> severity : <2>]");
+
+ // verify that Test1 was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test2" });
+
+ // remove annotation, error changes from can be null to unknown nullness
+ String test2CodeC = "package p1;\n" +
+ "public class Test2 {\n" +
+ " public Object bar() { return null; }\n" +
+ "}";
+ env.addClass( this.srcRoot, "p1", "Test2", test2CodeC );
+ incrementalBuild( this.projectPath );
+ expectingProblemsFor(test1Path,
+ "Problem : Null type safety: The expression of type 'Object' needs unchecked conversion to conform to \'@NonNull Object\' [ resource : range : <126,143> category : <90> severity : <1>]");
+
+ // verify that Test1 was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test2" });
+
+ // back to initial OK version (re-add @NonNull annotation)
+ env.addClass( this.srcRoot, "p1", "Test2", test2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that Test1 was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test2" });
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=373571
+ // incremental build that uses binary type for Test1 should not report spurious null errors.
+ public void testReturnAnnotationDependency02() throws JavaModelException, IOException {
+ // prepare the project:
+ setupProjectForNullAnnotations();
+
+ String test1Code = "package p1;\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "@NonNullByDefault\n" +
+ "public class Test1 {\n" +
+ " public void doStuff(int i) {\n" +
+ " }\n" +
+ "}";
+ env.addClass( this.srcRoot, "p1", "Test1", test1Code );
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ // add Test2
+ String test2Code = "package p1;\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "@NonNullByDefault\n" +
+ "public class Test2 extends Test1{\n" +
+ " @Override\n" +
+ " public void doStuff(int i) {\n" +
+ " super.doStuff(i);\n" +
+ " }\n" +
+ "}";
+ env.addClass( this.srcRoot, "p1", "Test2", test2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that Test2 only was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.Test2" });
+
+ // edit Test2 to delete annotation
+ test2Code = "package p1;\n" +
+ "public class Test2 extends Test1{\n" +
+ " @Override\n" +
+ " public void doStuff(int i) {\n" +
+ " super.doStuff(i);\n" +
+ " }\n" +
+ "}";
+ env.addClass( this.srcRoot, "p1", "Test2", test2Code );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ // verify that Test2 only was recompiled
+ expectingUniqueCompiledClasses(new String[] { "p1.Test2" });
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=411771
+ //[compiler][null] Enum constants not recognized as being NonNull.
+ //This test case exposes the bug mentioned in the defect. The enum
+ //definition comes from a file different from where it is accessed.
+ public void test411771a() throws IOException, JavaModelException {
+ setupProjectForNullAnnotations();
+ String testEnumCode = "package p1;\n" +
+ "enum TestEnum {FOO };\n";
+ env.addClass( this.srcRoot, "p1", "TestEnum", testEnumCode );
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ String nullTestCode = "package p1;\n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "public class NullTest {\n" +
+ " public static TestEnum bla() {\n" +
+ " @NonNull final TestEnum t = TestEnum.FOO;\n" +
+ " return t;\n" +
+ " }\n" +
+ "}";
+ env.addClass( this.srcRoot, "p1", "NullTest", nullTestCode );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ expectingUniqueCompiledClasses(new String[] { "p1.NullTest" });
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=411771
+ //[compiler][null] Enum constants not recognized as being NonNull.
+ //Distinguish between enum constant and enum type. The enum type should not
+ //be marked as NonNull.
+ public void test411771b() throws IOException, JavaModelException {
+ setupProjectForNullAnnotations();
+ String testEnumCode = "package p1;\n" +
+ "enum TestEnum { FOO };\n";
+ env.addClass( this.srcRoot, "p1", "TestEnum", testEnumCode );
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ String testClass = "package p1;\n" +
+ "public class X { TestEnum f; };\n";
+ env.addClass( this.srcRoot, "p1", "X", testClass );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ String nullTestCode = "package p1;\n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "public class NullTest {\n" +
+ " public static TestEnum bla(X x) {\n" +
+ " @NonNull final TestEnum t = x.f;\n" +
+ " return t;\n" +
+ " }\n" +
+ "}\n";
+ IPath test1Path = env.addClass( this.srcRoot, "p1", "NullTest", nullTestCode );
+ incrementalBuild( this.projectPath );
+
+ expectingProblemsFor(test1Path,
+ "Problem : Null type safety: The expression of type 'TestEnum' needs unchecked conversion to conform to " +
+ "'@NonNull TestEnum' [ resource : range : <144,147> category : <90> severity : <1>]");
+
+ expectingUniqueCompiledClasses(new String[] { "p1.NullTest" });
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=411771
+ //[compiler][null] Enum constants not recognized as being NonNull.
+ //A enum may contain fields other than predefined constants. We
+ //should not tag them as NonNull.
+ public void test411771c() throws IOException, JavaModelException {
+ setupProjectForNullAnnotations();
+ String testClass = "package p1;\n" +
+ "public class A {}";
+ env.addClass( this.srcRoot, "p1", "A", testClass );
+ fullBuild( this.projectPath );
+ expectingNoProblems();
+
+ String testEnumCode = "package p1;\n" +
+ "enum TestEnum {\n" +
+ " FOO;\n" +
+ " public static A a;" +
+ "};\n";
+ env.addClass( this.srcRoot, "p1", "TestEnum", testEnumCode );
+ incrementalBuild( this.projectPath );
+ expectingNoProblems();
+
+ String nullTestCode = "package p1;\n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "public class NullTest {\n" +
+ " public static TestEnum bla() {\n" +
+ " @NonNull final TestEnum t = TestEnum.FOO;\n" +
+ " return t;\n" +
+ " }\n" +
+ " public A testint() {\n" +
+ " @NonNull A a = TestEnum.a;\n" +
+ " return a;\n" +
+ " }\n" +
+ "}";
+ IPath test1Path = env.addClass( this.srcRoot, "p1", "NullTest", nullTestCode );
+ incrementalBuild( this.projectPath );
+ expectingProblemsFor(test1Path,
+ "Problem : Null type safety: The expression of type 'A' needs unchecked conversion to conform to " +
+ "'@NonNull A' [ resource : range : <208,218> category : <90> severity : <1>]");
+
+ expectingUniqueCompiledClasses(new String[] { "p1.NullTest" });
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BasicBuildTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BasicBuildTests.java
new file mode 100644
index 0000000000..89cb541d62
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BasicBuildTests.java
@@ -0,0 +1,640 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 392727 - Cannot compile project when a java file contains $ in its file name
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import java.util.Hashtable;
+
+import junit.framework.*;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+
+/**
+ * Basic tests of the image builder.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class BasicBuildTests extends BuilderTests {
+ public BasicBuildTests(String name) {
+ super(name);
+ }
+ static {
+// TESTS_NAMES = new String[] { "testBug392727" };
+ }
+ {
+ System.setProperty(JavaModelManager.MAX_COMPILED_UNITS_AT_ONCE, "0");
+ }
+ public static Test suite() {
+ return buildTestSuite(BasicBuildTests.class);
+ }
+
+ public void testBuild() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ }
+
+ /*
+ * http://bugs.eclipse.org/bugs/show_bug.cgi?id=23894
+ */
+ public void testToDoMarker() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_TASK_TAGS, "todo"); //$NON-NLS-1$
+ newOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL"); //$NON-NLS-1$
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath pathToA = env.addClass(root, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "//todo nothing\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingOnlySpecificProblemFor(pathToA, new Problem("A", "todo nothing", pathToA, 14, 26, -1, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ JavaCore.setOptions(options);
+ }
+
+ /*
+ * http://bugs.eclipse.org/bugs/show_bug.cgi?id=91426
+ */
+ public void testToDoMarker2() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_TASK_TAGS, "TODO,FIXME,XXX"); //$NON-NLS-1$
+ newOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,HIGH,LOW"); //$NON-NLS-1$
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath pathToA = env.addClass(root, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "//TODO normal\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public void foo() {\n"+ //$NON-NLS-1$
+ " //FIXME high\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ " public void foo2() {\n"+ //$NON-NLS-1$
+ " //XXX low\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ IMarker[] markers = env.getTaskMarkersFor(pathToA);
+ assertEquals("Wrong size", 3, markers.length);
+ try {
+ IMarker marker = markers[0];
+ Object priority = marker.getAttribute(IMarker.PRIORITY);
+ String message = (String) marker.getAttribute(IMarker.MESSAGE);
+ assertTrue("Wrong message", message.startsWith("TODO "));
+ assertNotNull("No task priority", priority);
+ assertEquals("Wrong priority", Integer.valueOf(IMarker.PRIORITY_NORMAL), priority);
+
+ marker = markers[1];
+ priority = marker.getAttribute(IMarker.PRIORITY);
+ message = (String) marker.getAttribute(IMarker.MESSAGE);
+ assertTrue("Wrong message", message.startsWith("FIXME "));
+ assertNotNull("No task priority", priority);
+ assertEquals("Wrong priority", Integer.valueOf(IMarker.PRIORITY_HIGH), priority);
+
+ marker = markers[2];
+ priority = marker.getAttribute(IMarker.PRIORITY);
+ message = (String) marker.getAttribute(IMarker.MESSAGE);
+ assertTrue("Wrong message", message.startsWith("XXX "));
+ assertNotNull("No task priority", priority);
+ assertEquals("Wrong priority", Integer.valueOf(IMarker.PRIORITY_LOW), priority);
+ } catch (CoreException e) {
+ assertTrue(false);
+ }
+ JavaCore.setOptions(options);
+ }
+
+ /*
+ * http://bugs.eclipse.org/bugs/show_bug.cgi?id=110797
+ */
+ public void testTags() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_TASK_TAGS, "TODO,FIXME,XXX"); //$NON-NLS-1$
+ newOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,HIGH,LOW"); //$NON-NLS-1$
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath pathToA = env.addClass(root, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "// TODO FIXME need to review the loop TODO should be done\n" + //$NON-NLS-1$
+ "public class A {\n" + //$NON-NLS-1$
+ "}");
+
+ fullBuild(projectPath);
+ IMarker[] markers = env.getTaskMarkersFor(pathToA);
+ assertEquals("Wrong size", 3, markers.length);
+ try {
+ IMarker marker = markers[2];
+ Object priority = marker.getAttribute(IMarker.PRIORITY);
+ String message = (String) marker.getAttribute(IMarker.MESSAGE);
+ assertEquals("Wrong message", "TODO should be done", message);
+ assertNotNull("No task priority", priority);
+ assertEquals("Wrong priority", Integer.valueOf(IMarker.PRIORITY_NORMAL), priority);
+
+ marker = markers[1];
+ priority = marker.getAttribute(IMarker.PRIORITY);
+ message = (String) marker.getAttribute(IMarker.MESSAGE);
+ assertEquals("Wrong message", "FIXME need to review the loop", message);
+ assertNotNull("No task priority", priority);
+ assertEquals("Wrong priority", Integer.valueOf(IMarker.PRIORITY_HIGH), priority);
+
+ marker = markers[0];
+ priority = marker.getAttribute(IMarker.PRIORITY);
+ message = (String) marker.getAttribute(IMarker.MESSAGE);
+ assertEquals("Wrong message", "TODO need to review the loop", message);
+ assertNotNull("No task priority", priority);
+ assertEquals("Wrong priority", Integer.valueOf(IMarker.PRIORITY_NORMAL), priority);
+ } catch (CoreException e) {
+ assertTrue(false);
+ }
+ JavaCore.setOptions(options);
+ }
+
+ /*
+ * http://bugs.eclipse.org/bugs/show_bug.cgi?id=110797
+ */
+ public void testTags2() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_TASK_TAGS, "TODO,FIXME,XXX"); //$NON-NLS-1$
+ newOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,HIGH,LOW"); //$NON-NLS-1$
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath pathToA = env.addClass(root, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "// TODO TODO need to review the loop\n" + //$NON-NLS-1$
+ "public class A {\n" + //$NON-NLS-1$
+ "}");
+
+ fullBuild(projectPath);
+ IMarker[] markers = env.getTaskMarkersFor(pathToA);
+ assertEquals("Wrong size", 2, markers.length);
+ try {
+ IMarker marker = markers[1];
+ Object priority = marker.getAttribute(IMarker.PRIORITY);
+ String message = (String) marker.getAttribute(IMarker.MESSAGE);
+ assertEquals("Wrong message", "TODO need to review the loop", message);
+ assertNotNull("No task priority", priority);
+ assertEquals("Wrong priority", Integer.valueOf(IMarker.PRIORITY_NORMAL), priority);
+
+ marker = markers[0];
+ priority = marker.getAttribute(IMarker.PRIORITY);
+ message = (String) marker.getAttribute(IMarker.MESSAGE);
+ assertEquals("Wrong message", "TODO need to review the loop", message);
+ assertNotNull("No task priority", priority);
+ assertEquals("Wrong priority", Integer.valueOf(IMarker.PRIORITY_NORMAL), priority);
+ } catch (CoreException e) {
+ assertTrue(false);
+ }
+ JavaCore.setOptions(options);
+ }
+
+ /*
+ * Ensures that a task tag is not user editable
+ * (regression test for bug 123721 two types of 'remove' for TODO task tags)
+ */
+ public void testTags3() throws CoreException {
+ Hashtable options = JavaCore.getOptions();
+
+ try {
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_TASK_TAGS, "TODO,FIXME,XXX"); //$NON-NLS-1$
+ newOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,HIGH,LOW"); //$NON-NLS-1$
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath pathToA = env.addClass(root, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "// TODO need to review\n" + //$NON-NLS-1$
+ "public class A {\n" + //$NON-NLS-1$
+ "}");
+
+ fullBuild(projectPath);
+ IMarker[] markers = env.getTaskMarkersFor(pathToA);
+ assertEquals("Marker should not be editable", Boolean.FALSE, markers[0].getAttribute(IMarker.USER_EDITABLE));
+ } finally {
+ JavaCore.setOptions(options);
+ }
+ }
+
+ /*
+ * http://bugs.eclipse.org/bugs/show_bug.cgi?id=92821
+ */
+ public void testUnusedImport() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_IMPORT, JavaCore.WARNING);
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "util", "MyException", //$NON-NLS-1$ //$NON-NLS-2$
+ "package util;\n" +
+ "public class MyException extends Exception {\n" +
+ " private static final long serialVersionUID = 1L;\n" +
+ "}"
+ ); //$NON-NLS-1$
+
+ env.addClass(root, "p", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;\n" +
+ "import util.MyException;\n" +
+ "public class Test {\n" +
+ " /**\n" +
+ " * @throws MyException\n" +
+ " */\n" +
+ " public void bar() {\n" +
+ " }\n" +
+ "}"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ JavaCore.setOptions(options);
+ }
+
+ /*
+ * http://bugs.eclipse.org/bugs/show_bug.cgi?id=98667
+ */
+ public void test98667() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Aaa$Bbb$Ccc", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n" + //$NON-NLS-1$
+ "\n" + //$NON-NLS-1$
+ "public class Aaa$Bbb$Ccc {\n" + //$NON-NLS-1$
+ "}" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ /**
+ * @bug 164707: ArrayIndexOutOfBoundsException in JavaModelManager if source level == 6.0
+ * @test Ensure that AIIOB does not longer happen with invalid source level string
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=164707"
+ */
+ public void testBug164707() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ IJavaProject javaProject = env.getJavaProject(projectPath);
+ javaProject.setOption(JavaCore.COMPILER_SOURCE, "invalid");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ /**
+ * @bug 75471: [prefs] no re-compile when loading settings
+ * @test Ensure that changing project preferences is well taking into account while rebuilding project
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=75471"
+ */
+ public void _testUpdateProjectPreferences() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "util", "MyException", //$NON-NLS-1$ //$NON-NLS-2$
+ "package util;\n" +
+ "public class MyException extends Exception {\n" +
+ " private static final long serialVersionUID = 1L;\n" +
+ "}"
+ ); //$NON-NLS-1$
+
+ IPath cuPath = env.addClass(root, "p", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;\n" +
+ "import util.MyException;\n" +
+ "public class Test {\n" +
+ "}"
+ );
+
+ fullBuild(projectPath);
+ expectingSpecificProblemFor(
+ projectPath,
+ new Problem("", "The import util.MyException is never used", cuPath, 18, 34, CategorizedProblem.CAT_UNNECESSARY_CODE, IMarker.SEVERITY_WARNING)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ project.setOption(JavaCore.COMPILER_PB_UNUSED_IMPORT, JavaCore.IGNORE);
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+ public void _testUpdateWkspPreferences() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "util", "MyException", //$NON-NLS-1$ //$NON-NLS-2$
+ "package util;\n" +
+ "public class MyException extends Exception {\n" +
+ " private static final long serialVersionUID = 1L;\n" +
+ "}"
+ ); //$NON-NLS-1$
+
+ IPath cuPath = env.addClass(root, "p", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;\n" +
+ "import util.MyException;\n" +
+ "public class Test {\n" +
+ "}"
+ );
+
+ fullBuild();
+ expectingSpecificProblemFor(
+ projectPath,
+ new Problem("", "The import util.MyException is never used", cuPath, 18, 34, CategorizedProblem.CAT_UNNECESSARY_CODE, IMarker.SEVERITY_WARNING)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Save preference
+ JavaModelManager manager = JavaModelManager.getJavaModelManager();
+ IEclipsePreferences preferences = manager.getInstancePreferences();
+ String unusedImport = preferences.get(JavaCore.COMPILER_PB_UNUSED_IMPORT, null);
+ try {
+ // Modify preference
+ preferences.put(JavaCore.COMPILER_PB_UNUSED_IMPORT, JavaCore.IGNORE);
+ incrementalBuild();
+ expectingNoProblems();
+ }
+ finally {
+ if (unusedImport == null) {
+ preferences.remove(JavaCore.COMPILER_PB_UNUSED_IMPORT);
+ } else {
+ preferences.put(JavaCore.COMPILER_PB_UNUSED_IMPORT, unusedImport);
+ }
+ }
+ }
+
+ public void testTags4() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_TASK_TAGS, "TODO!,TODO,TODO?"); //$NON-NLS-1$
+ newOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "HIGH,NORMAL,LOW"); //$NON-NLS-1$
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath pathToA = env.addClass(root, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "// TODO! TODO? need to review the loop\n" + //$NON-NLS-1$
+ "public class A {\n" + //$NON-NLS-1$
+ "}");
+
+ fullBuild(projectPath);
+ IMarker[] markers = env.getTaskMarkersFor(pathToA);
+ assertEquals("Wrong size", 2, markers.length);
+
+ try {
+ IMarker marker = markers[1];
+ Object priority = marker.getAttribute(IMarker.PRIORITY);
+ String message = (String) marker.getAttribute(IMarker.MESSAGE);
+ assertEquals("Wrong message", "TODO? need to review the loop", message);
+ assertNotNull("No task priority", priority);
+ assertEquals("Wrong priority", Integer.valueOf(IMarker.PRIORITY_LOW), priority);
+
+ marker = markers[0];
+ priority = marker.getAttribute(IMarker.PRIORITY);
+ message = (String) marker.getAttribute(IMarker.MESSAGE);
+ assertEquals("Wrong message", "TODO! need to review the loop", message);
+ assertNotNull("No task priority", priority);
+ assertEquals("Wrong priority", Integer.valueOf(IMarker.PRIORITY_HIGH), priority);
+ } catch (CoreException e) {
+ assertTrue(false);
+ }
+ JavaCore.setOptions(options);
+ }
+
+ // Bug 392727 - Cannot compile project when a java file contains $ in its file name
+ public void testBug392727() throws JavaModelException {
+ int save = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
+ try {
+ IPath projectPath = env.addProject("Project");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ // this class is the primary unit during build (see comment below)
+ env.addClass(root, "pack",
+ "Zork",
+ "package pack;\npublic class Zork { Main main; }\n" // pull in Main first
+ );
+
+ env.addClass(root, "pack", "Main",
+ "package pack;\n" +
+ "public class Main {\n" +
+ " Main$Sub sub;\n" + // indirectly pull in Main$Sub
+ "}\n"
+ );
+
+ env.addClass(root, "pack", "Main$Sub",
+ "package pack;\n" +
+ "public class Main$Sub { }\n"
+ );
+
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 1;
+
+ // Assumption regarding the order of compilation units:
+ // - org.eclipse.core.internal.dtree.AbstractDataTreeNode.assembleWith(AbstractDataTreeNode[], AbstractDataTreeNode[], boolean)
+ // assembles children array in lexical order, so "Zork.java" is last
+ // - org.eclipse.core.internal.watson.ElementTreeIterator.doIteration(DataTreeNode, IElementContentVisitor)
+ // iterates children last-to-first so "Zork.java" becomes first in sourceFiles of
+ // org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.addAllSourceFiles(ArrayList)
+ // - org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(SourceFile[])
+ // puts only "Zork.java" into 'toCompile' (due to MAX_AT_ONCE=1) and the others into 'remainingUnits'
+ // This ensures that NameEnvironment is setup with "Main.java" and "Main$Sub.java" both served from 'additionalUnits'
+ // which is essential for reproducing the bug.
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+ } finally {
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = save;
+ }
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=386901
+ public void testbBug386901() throws JavaModelException {
+
+ int previous = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
+ try {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "AB", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AB {} \n"+ //$NON-NLS-1$
+ "class AZ {}"); //$NON-NLS-1$
+
+ IPath pathToAA = env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA extends AZ {}"); //$NON-NLS-1$
+
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 1; // units compiled in batches of '1' unit
+ fullBuild(projectPath);
+ expectingProblemsFor(
+ pathToAA,
+ "Problem : AZ cannot be resolved to a type [ resource : range : <36,38> category : <40> severity : <2>]"
+ );
+
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 0; // All units compiled at once
+ fullBuild(projectPath);
+ expectingNoProblems();
+ } finally {
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = previous;
+ }
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=425420
+ public void testBug425420() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.5"); //$NON-NLS-1$
+ // don't env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath path = env.addClass(root, "", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "class X {\n" +
+ " void test() {\n" +
+ " int x = 0;\n" +
+ " int y = 0 >= 0 ? x : \"\"; \n" +
+ " }\n" +
+ "}");
+
+ fullBuild(projectPath);
+ expectingProblemsFor(
+ path,
+ "Problem : The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files [ resource : range : <0,1> category : <10> severity : <2>]"
+ );
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Bug530366Test.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Bug530366Test.java
new file mode 100644
index 0000000000..32eb03ae7c
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Bug530366Test.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Simeon Andreev and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.junit.internal.ArrayComparisonFailure;
+
+import junit.framework.Test;
+
+public class Bug530366Test extends BuilderTests {
+
+ private IPath project;
+ private IPath src;
+ private IPath somePackage;
+
+ public Bug530366Test(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(Bug530366Test.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ this.project = env.addProject("TestProjectBug530366");
+ env.addExternalJars(this.project, Util.getJavaClassLibs());
+
+ env.removePackageFragmentRoot(this.project, "");
+ this.src = env.addPackageFragmentRoot(this.project, "src");
+ this.somePackage = env.addPackage(this.src, "somepackage");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ env.removeProject(this.project);
+
+ super.tearDown();
+ }
+
+ /**
+ * Test for Bug 530366: Changing class name in source leads to missing inner class compilation artifact
+ *
+ * Given classes:
+ *
+ *
+ *
MyClass1, MyClass1$InnerClass, both defined in MyClass1.java
+ *
MyClass2, MyClass2$InnerClass, both defined in MyClass2.java
+ *
+ *
+ * Changing the name of the class in MyClass2.java inside a Java editor, from MyClass2 to MyClass1,
+ * results in overwriting the compiled .class file for MyClass1$InnerClass.
+ *
+ * Changing the name of the class in MyClass2.java inside a Java editor, from MyClass1 back to MyClass2,
+ * results in a missing .class file for MyClass1$InnerClass.
+ */
+ public void testBug530366() throws Exception {
+ defineNestingClass("MyClass1");
+ fullBuild();
+ expectingNoProblems();
+
+ IProject testProject = ResourcesPlugin.getWorkspace().getRoot().getProject("TestProjectBug530366");
+ IFile myClass1InnerClass = testProject.getFile("bin/somepackage/MyClass1$InnerClass.class");
+
+ URI compilationArtifactUri = myClass1InnerClass.getLocationURI();
+ byte[] expectedContents = Files.readAllBytes(Paths.get(compilationArtifactUri));
+
+ String sourceName = "MyClass2";
+ String className = "MyClass1"; // deliberately mismatched source and class names
+ IPath myClass2 = defineNestingClass(sourceName, className);
+
+ incrementalBuild();
+ expectProblems(myClass2);
+
+ byte[] actualContents = Files.readAllBytes(Paths.get(compilationArtifactUri));
+
+ assertEqualContents(expectedContents, actualContents);
+
+ redefineNestingClass("MyClass2");
+ incrementalBuild();
+ expectingNoProblems();
+
+ assertTrue("Java builder removed compilation artifact, but should not have",
+ myClass1InnerClass.exists());
+ }
+
+ private IPath redefineNestingClass(String className) {
+ env.removeClass(this.somePackage, className);
+ return defineNestingClass(className);
+ }
+
+ private IPath defineNestingClass(String className) {
+ return defineNestingClass(className, className);
+ }
+
+ private IPath defineNestingClass(String sourceName, String className) {
+ String classContents = String.join("\n"
+ , "package somepackage;"
+ , ""
+ , "public class " + className + " {"
+ , ""
+ , " public static class InnerClass {}"
+ , "}"
+ );
+ IPath source = env.addClass(this.src, "somepackage", sourceName, classContents);
+ return source;
+ }
+
+ private void expectProblems(IPath myClass2) {
+ Problem mismatchedSource = new Problem("", "The public type MyClass1 must be defined in its own file", myClass2, 35, 43, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR);
+ Problem alreadyDefined = new Problem("", "The type MyClass1 is already defined", myClass2, 35, 43, -1, IMarker.SEVERITY_ERROR);
+ Problem[] expectedProblems = { mismatchedSource, alreadyDefined };
+ expectingOnlySpecificProblemsFor(myClass2, expectedProblems);
+ }
+
+ private void assertEqualContents(byte[] expectedContents, byte[] actualContents) throws ArrayComparisonFailure {
+ String failMessage =
+ String.join(System.lineSeparator()
+ , "Java builder overwrote existing class file, but should not have"
+ , "expected class file contents: "
+ , new String(expectedContents)
+ , "actual class file contents: "
+ , new String(actualContents)
+ );
+ assertArrayEquals(failMessage, expectedContents, actualContents);
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Bug531382Test.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Bug531382Test.java
new file mode 100644
index 0000000000..2d9b9588a5
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Bug531382Test.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Simeon Andreev and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.compiler.BuildContext;
+import org.eclipse.jdt.core.tests.builder.ParticipantBuildTests.BuildTestParticipant;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.internal.core.builder.AbstractImageBuilder;
+
+import junit.framework.Test;
+
+public class Bug531382Test extends BuilderTests {
+
+ private IPath project;
+ private IPath src;
+ private IPath srcPackage;
+
+ private int previousLimit;
+
+ public Bug531382Test(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(Bug531382Test.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ this.project = env.addProject("TestProjectBug531382");
+ env.addExternalJars(this.project, Util.getJavaClassLibs());
+
+ env.removePackageFragmentRoot(this.project, "");
+ this.src = env.addPackageFragmentRoot(this.project, "src");
+ this.srcPackage = env.addPackage(this.src, "p");
+
+ /*
+ * We can work with the limit "as is", however that would mean creating a lot of classes.
+ * To improve test time we set the limit to a small number and then restore it once the test is done.
+ *
+ * This improvement can be removed if the field is to be hidden or made final.
+ */
+ this.previousLimit = AbstractImageBuilder.MAX_AT_ONCE;
+ AbstractImageBuilder.MAX_AT_ONCE = 42;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ TestBuilderParticipant.PARTICIPANT = null;
+
+ AbstractImageBuilder.MAX_AT_ONCE = this.previousLimit;
+
+ env.removeProject(this.project);
+
+ super.tearDown();
+ }
+
+ /**
+ * Test for Bug 531382.
+ *
+ * We create {@link AbstractImageBuilder#MAX_AT_ONCE} sources (e.g. 2000 sources).
+ *
+ * A build participant generates one more source during the build.
+ *
+ * We expect that this generated source is also compiled after the build.
+ * To check this we generate the source with an error for it, and we check for the error.
+ */
+ public void testBug531382() throws Exception {
+ IFolder srcPackageFolder = env.getWorkspace().getRoot().getFolder(this.srcPackage);
+ assertTrue("package in source must exist", srcPackageFolder.exists());
+
+ for (int i = 0; i < AbstractImageBuilder.MAX_AT_ONCE; ++i) {
+ env.addClass(this.src, "p", "X" + i, "package p;\n public class X" + i + " {}");
+ }
+
+ final IFile generatedFile = srcPackageFolder.getFile("Generated.java");
+ final String contents = "package p;\n public class NameMismatch {}";
+
+ class GenerateBrokenSource extends BuildTestParticipant {
+ public void buildStarting(BuildContext[] files, boolean isBatch) {
+ if (files.length > 0 && !generatedFile.exists()) {
+ BuildContext context = files[0];
+ createFile(generatedFile, contents);
+ IFile[] generatedFiles = { generatedFile };
+ context.recordAddedGeneratedFiles(generatedFiles);
+ }
+ }
+ }
+ // Creating this sets the build participant singleton.
+ new GenerateBrokenSource();
+
+ assertFalse("source to be generated from build participant should not exist before build", generatedFile.exists());
+ fullBuild(this.project);
+ assertTrue("expected source to be generated from build participant", generatedFile.exists());
+
+ expectCompileProblem("The public type NameMismatch must be defined in its own file");
+ }
+
+ protected void createFile(IFile generatedFile, String contents) {
+ boolean force = true;
+ IProgressMonitor monitor = new NullProgressMonitor();
+ try {
+ generatedFile.create(new ByteArrayInputStream(contents.getBytes()), force, monitor);
+ generatedFile.setDerived(true, monitor);
+ } catch (CoreException e) {
+ throw new AssertionError("failed to generate file in build participant", e);
+ }
+ }
+
+ private void expectCompileProblem(String expectedProblemMessage) {
+ List actualProblemMessages = new ArrayList<>();
+ Problem[] problems = env.getProblemsFor(this.project, "org.eclipse.jdt.core.tests.compile.problem");
+ if (problems != null) {
+ for (Problem problem : problems) {
+ actualProblemMessages.add(problem.getMessage());
+ }
+ }
+
+ List expectedProblemMessages = Arrays.asList(expectedProblemMessage);
+ assertEquals("expected build participant to cause compile problems",
+ expectedProblemMessages, actualProblemMessages);
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BuilderTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BuilderTests.java
new file mode 100644
index 0000000000..e2451de87e
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BuilderTests.java
@@ -0,0 +1,605 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+import junit.framework.*;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.tests.junit.extension.TestCase;
+import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
+import org.eclipse.jdt.core.tests.util.TestVerifier;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+/**
+ * Base class for Java image builder tests
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class BuilderTests extends TestCase {
+ protected static boolean DEBUG = false;
+ protected static TestingEnvironment env = null;
+ protected EfficiencyCompilerRequestor debugRequestor = null;
+
+ public BuilderTests(String name) {
+ super(name);
+ }
+
+ protected void cleanBuild() {
+ this.debugRequestor.clearResult();
+ this.debugRequestor.activate();
+ env.cleanBuild();
+ this.debugRequestor.deactivate();
+ }
+
+ protected void cleanBuild(String name) {
+ this.debugRequestor.clearResult();
+ this.debugRequestor.activate();
+ env.cleanBuild(name);
+ this.debugRequestor.deactivate();
+ }
+
+ /** Execute the given class. Expecting output and error must be specified.
+ */
+ protected void executeClass(
+ IPath projectPath,
+ String className,
+ String expectingOutput,
+ String expectedError) {
+ TestVerifier verifier = new TestVerifier(false);
+ Vector classpath = new Vector(5);
+
+ IPath workspacePath = env.getWorkspaceRootPath();
+
+ classpath.addElement(workspacePath.append(env.getOutputLocation(projectPath)).toOSString());
+ IClasspathEntry[] cp = env.getClasspath(projectPath);
+ for (int i = 0; i < cp.length; i++) {
+ IPath c = cp[i].getPath();
+ String ext = c.getFileExtension();
+ if (ext != null && (ext.equals("zip") || ext.equals("jar"))) { //$NON-NLS-1$ //$NON-NLS-2$
+ if (c.getDevice() == null) {
+ classpath.addElement(workspacePath.append(c).toOSString());
+ } else {
+ classpath.addElement(c.toOSString());
+ }
+ }
+ }
+
+ verifier.execute(className, (String[]) classpath.toArray(new String[0]));
+
+ if (DEBUG) {
+ System.out.println("ERRORS\n"); //$NON-NLS-1$
+ System.out.println(Util.displayString(verifier.getExecutionError()));
+
+ System.out.println("OUTPUT\n"); //$NON-NLS-1$
+ System.out.println(Util.displayString(verifier.getExecutionOutput()));
+ }
+ String actualError = verifier.getExecutionError();
+
+ // workaround pb on 1.3.1 VM (line delimitor is not the platform line delimitor)
+ char[] error = actualError.toCharArray();
+ actualError = new String(CharOperation.replace(error, System.getProperty("line.separator").toCharArray(), new char[] { '\n' })); //$NON-NLS-1$
+
+ if (actualError.indexOf(expectedError) == -1) {
+ System.out.println("ERRORS\n"); //$NON-NLS-1$
+ System.out.println(Util.displayString(actualError));
+ }
+ assertTrue("unexpected error : " + actualError + " expected : " + expectedError, actualError.indexOf(expectedError) != -1); //$NON-NLS-1$ //$NON-NLS-2$
+
+ String actualOutput = verifier.getExecutionOutput();
+ if (actualOutput.indexOf(expectingOutput) == -1) {
+ System.out.println("OUTPUT\n"); //$NON-NLS-1$
+ System.out.println(Util.displayString(actualOutput));
+ }
+ assertTrue("unexpected output :" + actualOutput + " expected: " + expectingOutput, actualOutput.indexOf(expectingOutput) != -1); //$NON-NLS-1$
+
+ }
+
+ protected void expectingParticipantProblems(IPath path, String expected) {
+ Problem[] problems = env.getProblemsFor(path, "org.eclipse.jdt.core.tests.compile.problem");
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0, length = problems.length; i < length; i++) {
+ Problem problem = problems[i];
+ buf.append(problem.getMessage());
+ if (i < length - 1) buf.append('\n');
+ }
+ assertEquals("Unexpected problems", expected, buf.toString());
+ }
+
+ /** Verifies that given element is not present.
+ */
+ protected void expectingPresenceOf(IPath path) {
+ expectingPresenceOf(new IPath[] { path });
+ }
+
+ /** Verifies that given elements are not present.
+ */
+ protected void expectingPresenceOf(IPath[] paths) {
+ IPath wRoot = env.getWorkspaceRootPath();
+
+ for (int i = 0; i < paths.length; i++)
+ assertTrue(paths[i] + " is not present", wRoot.append(paths[i]).toFile().exists()); //$NON-NLS-1$
+ }
+
+ /** Verifies that given element is not present.
+ */
+ protected void expectingNoPresenceOf(IPath path) {
+ expectingNoPresenceOf(new IPath[] { path });
+ }
+
+ /** Verifies that given elements are not present.
+ */
+ protected void expectingNoPresenceOf(IPath[] paths) {
+ IPath wRoot = env.getWorkspaceRootPath();
+
+ for (int i = 0; i < paths.length; i++)
+ assertTrue(paths[i] + " is present", !wRoot.append(paths[i]).toFile().exists()); //$NON-NLS-1$
+ }
+
+ /** Verifies that given classes have been compiled.
+ */
+ protected void expectingCompiledClasses(String[] expected) {
+ String[] actual = this.debugRequestor.getCompiledClasses();
+ org.eclipse.jdt.internal.core.util.Util.sort(actual);
+ org.eclipse.jdt.internal.core.util.Util.sort(expected);
+ expectingCompiling(actual, expected, "unexpected recompiled units"); //$NON-NLS-1$
+ }
+
+ /**
+ * Verifies that the given classes and no others have been compiled,
+ * but permits the classes to have been compiled more than once.
+ */
+ protected void expectingUniqueCompiledClasses(String[] expected) {
+ String[] actual = this.debugRequestor.getCompiledClasses();
+ org.eclipse.jdt.internal.core.util.Util.sort(actual);
+ // Eliminate duplicate entries
+ int dups = 0;
+ for (int i = 0; i < actual.length - 1; ++i) {
+ if (actual[i + 1].equals(actual[i])) {
+ ++dups;
+ actual[i] = null;
+ }
+ }
+ String[] uniqueActual = new String[actual.length - dups];
+ for (int i = 0, j = 0; i < actual.length; ++i) {
+ if (actual[i] != null) {
+ uniqueActual[j++] = actual[i];
+ }
+ }
+ org.eclipse.jdt.internal.core.util.Util.sort(expected);
+ expectingCompiling(uniqueActual, expected, "unexpected compiled units"); //$NON-NLS-1$
+ }
+
+ /** Verifies that given classes have been compiled in the specified order.
+ */
+ protected void expectingCompilingOrder(String[] expected) {
+ expectingCompiling(this.debugRequestor.getCompiledFiles(), expected, "unexpected compiling order"); //$NON-NLS-1$
+ }
+
+ private void expectingCompiling(String[] actual, String[] expected, String message) {
+ if (DEBUG)
+ for (int i = 0; i < actual.length; i++)
+ System.out.println(actual[i]);
+
+ StringBuffer actualBuffer = new StringBuffer("{ "); //$NON-NLS-1$
+ for (int i = 0; i < actual.length; i++) {
+ if (i > 0)
+ actualBuffer.append(", "); //$NON-NLS-1$
+ actualBuffer.append("\"");
+ actualBuffer.append(actual[i]);
+ actualBuffer.append("\"");
+ }
+ actualBuffer.append(" }");
+ StringBuffer expectedBuffer = new StringBuffer("{ "); //$NON-NLS-1$
+ for (int i = 0; i < expected.length; i++) {
+ if (i > 0)
+ expectedBuffer.append(", "); //$NON-NLS-1$
+ expectedBuffer.append("\"");
+ expectedBuffer.append(expected[i]);
+ expectedBuffer.append("\"");
+ }
+ expectedBuffer.append(" }");
+ assertEquals(message, expectedBuffer.toString(), actualBuffer.toString());
+ }
+
+ /** Verifies that the workspace has no problems.
+ */
+ protected void expectingNoProblems() {
+ expectingNoProblemsFor(env.getWorkspaceRootPath());
+ }
+
+ /** Verifies that the given element has no problems.
+ */
+ protected void expectingNoProblemsFor(IPath root) {
+ expectingNoProblemsFor(new IPath[] { root });
+ }
+
+ /** Verifies that the given elements have no problems.
+ */
+ protected void expectingNoProblemsFor(IPath[] roots) {
+ StringBuffer buffer = new StringBuffer();
+ Problem[] allProblems = allSortedProblems(roots);
+ if (allProblems != null) {
+ for (int i=0, length=allProblems.length; i expected.length) {
+ for (Enumeration e = actual.elements(); e.hasMoreElements();) {
+ IPath path = (IPath) e.nextElement();
+ boolean found = false;
+ for (int i = 0; i < expected.length; ++i) {
+ if (path.equals(expected[i])) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ assertTrue("unexpected problem(s) with " + path.toString(), false); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /** Verifies that the given element has a specific problem and
+ * only the given problem.
+ */
+ protected void expectingOnlySpecificProblemFor(IPath root, Problem problem) {
+ expectingOnlySpecificProblemsFor(root, new Problem[] { problem });
+ }
+
+ /** Verifies that the given element has specifics problems and
+ * only the given problems.
+ */
+ protected void expectingOnlySpecificProblemsFor(IPath root, Problem[] expectedProblems) {
+ if (DEBUG)
+ printProblemsFor(root);
+
+ Problem[] rootProblems = env.getProblemsFor(root);
+
+ for (int i = 0; i < expectedProblems.length; i++) {
+ Problem expectedProblem = expectedProblems[i];
+ boolean found = false;
+ for (int j = 0; j < rootProblems.length; j++) {
+ if(expectedProblem.equals(rootProblems[j])) {
+ found = true;
+ rootProblems[j] = null;
+ break;
+ }
+ }
+ if (!found) {
+ printProblemsFor(root);
+ }
+ assertTrue("problem not found: " + expectedProblem.toString(), found); //$NON-NLS-1$
+ }
+ for (int i = 0; i < rootProblems.length; i++) {
+ if(rootProblems[i] != null) {
+ printProblemsFor(root);
+ assertTrue("unexpected problem: " + rootProblems[i].toString(), false); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /** Verifies that the given element has problems.
+ */
+ protected void expectingProblemsFor(IPath root, String expected) {
+ expectingProblemsFor(new IPath[] { root }, expected);
+ }
+
+ /** Verifies that the given elements have problems.
+ */
+ protected void expectingProblemsFor(IPath[] roots, String expected) {
+ Problem[] problems = allSortedProblems(roots);
+ assumeEquals("Invalid problem(s)!!!", expected, arrayToString(problems)); //$NON-NLS-1$
+ }
+
+ /**
+ * Verifies that the given element has the expected problems.
+ */
+ protected void expectingProblemsFor(IPath root, List expected) {
+ expectingProblemsFor(new IPath[] { root }, expected);
+ }
+
+ /**
+ * Verifies that the given elements have the expected problems.
+ */
+ protected void expectingProblemsFor(IPath[] roots, List expected) {
+ Problem[] allProblems = allSortedProblems(roots);
+ assumeEquals("Invalid problem(s)!!!", arrayToString(expected.toArray()), arrayToString(allProblems));
+ }
+
+ /** Verifies that the given element has a specific problem.
+ */
+ protected void expectingSpecificProblemFor(IPath root, Problem problem) {
+ expectingSpecificProblemsFor(root, new Problem[] { problem });
+ }
+
+ /** Verifies that the given element has specific problems.
+ */
+ protected void expectingSpecificProblemsFor(IPath root, Problem[] problems) {
+ if (DEBUG)
+ printProblemsFor(root);
+
+ Problem[] rootProblems = env.getProblemsFor(root);
+ next : for (int i = 0; i < problems.length; i++) {
+ Problem problem = problems[i];
+ for (int j = 0; j < rootProblems.length; j++) {
+ Problem rootProblem = rootProblems[j];
+ if (rootProblem != null) {
+ if (problem.equals(rootProblem)) {
+ rootProblems[j] = null;
+ continue next;
+ }
+ }
+ }
+ /*
+ for (int j = 0; j < rootProblems.length; j++) {
+ Problem pb = rootProblems[j];
+ if (pb != null) {
+ System.out.print("got pb: new Problem(\"" + pb.getLocation() + "\", \"" + pb.getMessage() + "\", \"" + pb.getResourcePath() + "\"");
+ System.out.print(", " + pb.getStart() + ", " + pb.getEnd() + ", " + pb.getCategoryId()+ ", " + pb.getSeverity());
+ System.out.println(")");
+ }
+ }
+ */
+ System.out.println("--------------------------------------------------------------------------------");
+ System.out.println("Missing problem while running test "+getName()+":");
+ System.out.println(" - expected : " + problem);
+ System.out.println(" - current: " + arrayToString(rootProblems));
+ assumeTrue("missing expected problem: " + problem, false);
+ }
+ }
+
+ /** Batch builds the workspace.
+ */
+ protected void fullBuild() {
+ this.debugRequestor.clearResult();
+ this.debugRequestor.activate();
+ env.fullBuild();
+ this.debugRequestor.deactivate();
+ }
+
+ /** Batch builds the given project.
+ */
+ protected void fullBuild(IPath projectPath) {
+ this.debugRequestor.clearResult();
+ this.debugRequestor.activate();
+ env.fullBuild(projectPath);
+ this.debugRequestor.deactivate();
+ }
+
+ /** Incrementally builds the given project.
+ */
+ protected void incrementalBuild(IPath projectPath) {
+ this.debugRequestor.clearResult();
+ this.debugRequestor.activate();
+ env.incrementalBuild(projectPath);
+ this.debugRequestor.deactivate();
+ }
+
+ /** Incrementally builds the workspace.
+ */
+ protected void incrementalBuild() {
+ this.debugRequestor.clearResult();
+ this.debugRequestor.activate();
+ env.incrementalBuild();
+ this.debugRequestor.deactivate();
+ }
+
+ protected void printProblems() {
+ printProblemsFor(env.getWorkspaceRootPath());
+ }
+
+ protected void printProblemsFor(IPath root) {
+ printProblemsFor(new IPath[] { root });
+ }
+
+ protected void printProblemsFor(IPath[] roots) {
+ for (int i = 0; i < roots.length; i++) {
+ IPath path = roots[i];
+
+ /* get the leaf problems for this type */
+ Problem[] problems = env.getProblemsFor(path);
+ System.out.println(arrayToString(problems));
+ System.out.println();
+ }
+ }
+
+ protected String arrayToString(Object[] array) {
+ StringBuffer buffer = new StringBuffer();
+ int length = array == null ? 0 : array.length;
+ for (int i = 0; i < length; i++) {
+ if (array[i] != null) {
+ if (i > 0) buffer.append('\n');
+ buffer.append(array[i].toString());
+ }
+ }
+ return buffer.toString();
+ }
+
+ /** Sets up this test.
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ this.debugRequestor = new EfficiencyCompilerRequestor();
+ Compiler.DebugRequestor = this.debugRequestor;
+ if (env == null) {
+ env = new TestingEnvironment();
+ env.openEmptyWorkspace();
+ }
+ env.resetWorkspace();
+
+ }
+ /**
+ * @see junit.framework.TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ env.resetWorkspace();
+ JavaCore.setOptions(JavaCore.getDefaultOptions());
+ super.tearDown();
+ }
+
+ /**
+ * Concatenate and sort all problems for given root paths.
+ *
+ * @param roots The path to get the problems
+ * @return All sorted problems of all given path
+ */
+ Problem[] allSortedProblems(IPath[] roots) {
+ Problem[] allProblems = null;
+ for (int i = 0, max=roots.length; i range : <-1,-1> category : <10> severity : <");
+ jdkLevelProblem.append(severity);
+ jdkLevelProblem.append(">]");
+ return jdkLevelProblem.toString();
+}
+
+public void testClasspathFileChange() throws JavaModelException {
+ // create project with src folder, and alternate unused src2 folder
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ IPath classTest1 = env.addClass(root, "p1", "Test1", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Test1 extends Zork1 {}" //$NON-NLS-1$
+ );
+ // not yet on the classpath
+ IPath src2Path = env.addFolder(projectPath, "src2"); //$NON-NLS-1$
+ IPath src2p1Path = env.addFolder(src2Path, "p1"); //$NON-NLS-1$
+ env.addFile(src2p1Path, "Zork1.java", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Zork1 {}" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingSpecificProblemFor(classTest1, new Problem("src", "Zork1 cannot be resolved to a type", classTest1,39, 44, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ //----------------------------
+ // Step 2
+ //----------------------------
+ StringBuffer buffer = new StringBuffer("\n"); //$NON-NLS-1$
+ buffer.append("\n"); //$NON-NLS-1$
+ buffer.append(" \n"); //$NON-NLS-1$
+ buffer.append(" \n"); // add src2 on classpath through resource change //$NON-NLS-1$
+ String[] classlibs = Util.getJavaClassLibs();
+ for (int i = 0; i < classlibs.length; i++) {
+ buffer.append(" \n"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ buffer.append(" \n"); //$NON-NLS-1$
+ buffer.append(""); //$NON-NLS-1$
+ boolean wasAutoBuilding = env.isAutoBuilding();
+ try {
+ // turn autobuild on
+ env.setAutoBuilding(true);
+ // write new .classpath, will trigger autobuild
+ env.addFile(projectPath, ".classpath", buffer.toString()); //$NON-NLS-1$
+ // ensures the builder did see the classpath change
+ env.waitForAutoBuild();
+ expectingNoProblems();
+ } finally {
+ env.setAutoBuilding(wasAutoBuilding);
+ }
+}
+
+public void testClosedProject() throws JavaModelException, IOException {
+ IPath project1Path = env.addProject("CP1"); //$NON-NLS-1$
+ IProject project1 = ResourcesPlugin.getWorkspace().getRoot().getProject("CP1");
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ String jarFile = project1.getLocation().toOSString() + File.separator + "temp.jar";
+
+ org.eclipse.jdt.core.tests.util.Util.createEmptyJar(
+ jarFile,
+ JavaCore.VERSION_1_4);
+
+ IPath jarPath = null;
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(jarFile);
+ int length = fis.available();
+ byte[] jarContent = new byte[length];
+ fis.read(jarContent);
+ jarPath = env.addInternalJar(project1Path, "temp.jar", jarContent); //$NON-NLS-1$
+ }
+ finally {
+ if (fis != null) fis.close();
+ }
+
+ IPath project2Path = env.addProject("CP2"); //$NON-NLS-1$
+ env.addExternalJars(project2Path, Util.getJavaClassLibs());
+ env.addRequiredProject(project2Path, project1Path);
+
+ IPath project3Path = env.addProject("CP3"); //$NON-NLS-1$
+ env.addExternalJars(project3Path, Util.getJavaClassLibs());
+ env.addExternalJar(project3Path, jarPath.toString());
+
+ fullBuild();
+ expectingNoProblems();
+
+ //----------------------------
+ // Step 2
+ //----------------------------
+ env.closeProject(project1Path);
+
+ incrementalBuild();
+ expectingOnlyProblemsFor(new IPath[] {project2Path, project3Path});
+ expectingOnlySpecificProblemsFor(project2Path,
+ new Problem[] {
+ new Problem("", "The project cannot be built until build path errors are resolved", project2Path, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR), //$NON-NLS-1$ //$NON-NLS-2$
+ new Problem("Build path", "Project 'CP2' is missing required Java project: 'CP1'", project2Path, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR) //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ );
+ expectingOnlySpecificProblemsFor(project3Path,
+ new Problem[] {
+ new Problem("", "The project cannot be built until build path errors are resolved", project3Path, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR), //$NON-NLS-1$ //$NON-NLS-2$
+ new Problem("Build path", "Project 'CP3' is missing required library: '/CP1/temp.jar'", project3Path, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR) //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ );
+
+ env.openProject(project1Path);
+ incrementalBuild();
+ expectingNoProblems();
+
+ //----------------------------
+ // Step 3
+ //----------------------------
+ Hashtable options = JavaCore.getOptions();
+ options.put(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, JavaCore.IGNORE);
+ JavaCore.setOptions(options);
+ env.closeProject(project1Path);
+ env.waitForManualRefresh();
+ incrementalBuild();
+ env.waitForAutoBuild();
+ expectingOnlyProblemsFor(new IPath[] {project2Path, project3Path});
+ expectingOnlySpecificProblemFor(project2Path,
+ new Problem("Build path", "Project 'CP2' is missing required Java project: 'CP1'", project2Path, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR) //$NON-NLS-1$ //$NON-NLS-2$
+ );
+ expectingOnlySpecificProblemFor(project3Path,
+ new Problem("Build path", "Project 'CP3' is missing required library: '/CP1/temp.jar'", project3Path, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR) //$NON-NLS-1$ //$NON-NLS-2$
+ );
+
+ env.openProject(project1Path);
+ incrementalBuild();
+ expectingNoProblems();
+ env.removeProject(project1Path);
+}
+
+public void testCorruptBuilder() throws JavaModelException {
+ IPath project1Path = env.addProject("P1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ env.addClass(project1Path, "p", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;" + //$NON-NLS-1$
+ "public class Test {}" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingNoProblems();
+
+ IPath outputFolderPackage = env.getOutputLocation(project1Path).append("p"); //$NON-NLS-1$
+ env.removeBinaryClass(outputFolderPackage, "Test"); //$NON-NLS-1$
+
+ IPath subTest = env.addClass(project1Path, "", "SubTest", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class SubTest extends p.Test {}" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ expectingOnlySpecificProblemFor(subTest, new Problem("", "p.Test cannot be resolved to a type", subTest, 29, 35, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$)
+
+ env.addClass(project1Path, "p", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;" + //$NON-NLS-1$
+ "public class Test {}" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingNoProblems();
+
+ Hashtable options = JavaCore.getOptions();
+ options.put(JavaCore.CORE_JAVA_BUILD_RECREATE_MODIFIED_CLASS_FILES_IN_OUTPUT_FOLDER, JavaCore.ENABLED);
+ JavaCore.setOptions(options);
+
+ env.removeBinaryClass(outputFolderPackage, "Test"); //$NON-NLS-1$
+ env.waitForManualRefresh();
+ incrementalBuild();
+ env.waitForAutoBuild();
+ expectingNoProblems();
+ env.removeProject(project1Path);
+}
+
+public void testCorruptBuilder2() throws JavaModelException {
+ IPath project1Path = env.addProject("P2"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+ env.removePackageFragmentRoot(project1Path, ""); //$NON-NLS-1$
+ IPath src = env.addPackageFragmentRoot(project1Path, "src"); //$NON-NLS-1$
+ IPath bin = env.setOutputFolder(project1Path, "bin"); //$NON-NLS-1$
+
+ env.addClass(src, "p", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;" + //$NON-NLS-1$
+ "public class Test {}" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ env.waitForAutoBuild();
+ expectingNoProblems();
+
+ IPath outputFolderPackage = bin.append("p"); //$NON-NLS-1$
+ env.removeBinaryClass(outputFolderPackage, "Test"); //$NON-NLS-1$
+
+ IPath subTest = env.addClass(src, "p2", "SubTest", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;" + //$NON-NLS-1$
+ "public class SubTest extends p.Test {}" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ env.waitForAutoBuild();
+ expectingOnlySpecificProblemFor(subTest, new Problem("", "p.Test cannot be resolved to a type", subTest, 40, 46, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$)
+
+ env.addClass(src, "p", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;" + //$NON-NLS-1$
+ "public class Test {}" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ env.waitForAutoBuild();
+ expectingNoProblems();
+
+ Hashtable options = JavaCore.getOptions();
+ options.put(JavaCore.CORE_JAVA_BUILD_RECREATE_MODIFIED_CLASS_FILES_IN_OUTPUT_FOLDER, JavaCore.ENABLED);
+ JavaCore.setOptions(options);
+
+ env.removeBinaryClass(outputFolderPackage, "Test"); //$NON-NLS-1$
+ env.waitForManualRefresh();
+ incrementalBuild();
+ expectingNoProblems();
+ env.removeProject(project1Path);
+}
+
+/*
+ * Ensures that changing a type in an external folder and refreshing triggers a rebuild
+ */
+public void testChangeExternalFolder() throws CoreException {
+ String externalLib = Util.getOutputDirectory() + File.separator + "externalLib";
+ IPath projectPath = env.addProject("Project");
+ try {
+ new File(externalLib).mkdirs();
+ Util.compile(
+ new String[] {
+ "p/X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ " public void foo() {\n" +
+ " }\n" +
+ "}"
+ },
+ new HashMap(),
+ externalLib
+ );
+
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.addExternalFolders(projectPath, new String[] {externalLib});
+
+ IPath root = env.getPackageFragmentRootPath(projectPath, ""); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "");
+
+ IPath classY = env.addClass(root, "q", "Y",
+ "package q;\n"+
+ "public class Y {\n" +
+ " void bar(p.X x) {\n" +
+ " x.foo();\n" +
+ " }\n" +
+ "}"
+ );
+
+ fullBuild(projectPath);
+ env.waitForAutoBuild();
+ expectingNoProblems();
+
+ String externalClassFile = externalLib + File.separator + "p" + File.separator + "X.class";
+ long lastModified = new java.io.File(externalClassFile).lastModified();
+ try {
+ Thread.sleep(1000);
+ } catch(InterruptedException e) {
+ }
+ Util.compile(
+ new String[] {
+ "p/X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ "}"
+ },
+ new HashMap(),
+ externalLib
+ );
+ new java.io.File(externalClassFile).setLastModified(lastModified + 1000); // to be sure its different
+
+ env.getProject(projectPath).refreshLocal(IResource.DEPTH_INFINITE, null);
+ env.waitForManualRefresh();
+
+ incrementalBuild(projectPath);
+ env.waitForAutoBuild();
+ expectingProblemsFor(
+ classY,
+ "Problem : The method foo() is undefined for the type X [ resource : range : <54,57> category : <50> severity : <2>]"
+ );
+ } finally {
+ new File(externalLib).delete();
+ env.removeProject(projectPath);
+ }
+}
+
+/*
+ * Ensures that changing a type in an external ZIP archive and refreshing triggers a rebuild
+ */
+public void testChangeZIPArchive1() throws Exception {
+ String externalLib = Util.getOutputDirectory() + File.separator + "externalLib.abc";
+ IPath projectPath = env.addProject("Project");
+ try {
+ org.eclipse.jdt.core.tests.util.Util.createJar(
+ new String[] {
+ "p/X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ " public void foo() {\n" +
+ " }\n" +
+ "}"
+ },
+ externalLib,
+ "1.4");
+
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.addExternalJars(projectPath, new String[] {externalLib});
+
+ IPath root = env.getPackageFragmentRootPath(projectPath, ""); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "");
+
+ IPath classY = env.addClass(root, "q", "Y",
+ "package q;\n"+
+ "public class Y {\n" +
+ " void bar(p.X x) {\n" +
+ " x.foo();\n" +
+ " }\n" +
+ "}"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ org.eclipse.jdt.core.tests.util.Util.createJar(
+ new String[] {
+ "p/X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ "}"
+ },
+ externalLib,
+ "1.4");
+
+ IJavaProject p = env.getJavaProject(projectPath);
+ p.getJavaModel().refreshExternalArchives(new IJavaElement[] {p}, null);
+
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ classY,
+ "Problem : The method foo() is undefined for the type X [ resource : range : <54,57> category : <50> severity : <2>]"
+ );
+ } finally {
+ new File(externalLib).delete();
+ env.removeProject(projectPath);
+ }
+}
+
+/*
+ * Ensures that changing a type in an internal ZIP archive and refreshing triggers a rebuild
+ */
+public void testChangeZIPArchive2() throws Exception {
+ IPath projectPath = env.addProject("Project");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ String internalLib = env.getProject("Project").getLocation().toOSString() + File.separator + "internalLib.abc";
+ org.eclipse.jdt.core.tests.util.Util.createJar(
+ new String[] {
+ "p/X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ " public void foo() {\n" +
+ " }\n" +
+ "}"
+ },
+ internalLib,
+ "1.4");
+ env.getProject(projectPath).refreshLocal(IResource.DEPTH_INFINITE, null);
+ env.addEntry(projectPath, JavaCore.newLibraryEntry(new Path("/Project/internalLib.abc"), null, null));
+
+ IPath root = env.getPackageFragmentRootPath(projectPath, ""); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "");
+
+ IPath classY = env.addClass(root, "q", "Y",
+ "package q;\n"+
+ "public class Y {\n" +
+ " void bar(p.X x) {\n" +
+ " x.foo();\n" +
+ " }\n" +
+ "}"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ org.eclipse.jdt.core.tests.util.Util.createJar(
+ new String[] {
+ "p/X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ "}"
+ },
+ internalLib,
+ "1.4");
+
+ env.getProject(projectPath).refreshLocal(IResource.DEPTH_INFINITE, null);
+
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ classY,
+ "Problem : The method foo() is undefined for the type X [ resource : range : <54,57> category : <50> severity : <2>]"
+ );
+ env.removeProject(projectPath);
+}
+
+/*
+ * Ensures that changing an external jar and refreshing the projects triggers a rebuild
+ * (regression test for bug 50207 Compile errors fixed by 'refresh' do not reset problem list or package explorer error states)
+ */
+public void testExternalJarChange() throws JavaModelException, IOException {
+ // setup
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ IPath root = env.getPackageFragmentRootPath(projectPath, ""); //$NON-NLS-1$
+ IPath classTest = env.addClass(root, "p", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;\n"+ //$NON-NLS-1$
+ "public class X {\n" + //$NON-NLS-1$
+ " void foo() {\n" + //$NON-NLS-1$
+ " new q.Y().bar();\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}" //$NON-NLS-1$
+ );
+ String externalJar = Util.getOutputDirectory() + File.separator + "test.jar"; //$NON-NLS-1$
+ Util.createJar(
+ new String[] {
+ "q/Y.java", //$NON-NLS-1$
+ "package q;\n" + //$NON-NLS-1$
+ "public class Y {\n" + //$NON-NLS-1$
+ "}" //$NON-NLS-1$
+ },
+ new HashMap(),
+ externalJar
+ );
+ env.addExternalJar(projectPath, externalJar);
+
+ // build -> expecting problems
+ fullBuild();
+ expectingProblemsFor(
+ classTest,
+ "Problem : The method bar() is undefined for the type Y [ resource : range : <57,60> category : <50> severity : <2>]"
+ );
+
+ // fix jar
+ Util.createJar(
+ new String[] {
+ "q/Y.java", //$NON-NLS-1$
+ "package q;\n" + //$NON-NLS-1$
+ "public class Y {\n" + //$NON-NLS-1$
+ " public void bar() {\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}" //$NON-NLS-1$
+ },
+ new HashMap(),
+ externalJar
+ );
+
+ // refresh project and rebuild -> expecting no problems
+ IJavaProject project = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getProject("Project")); //$NON-NLS-1$
+ project.getJavaModel().refreshExternalArchives(new IJavaElement[] {project}, null);
+ incrementalBuild();
+ expectingNoProblems();
+ env.removeProject(projectPath);
+}
+
+public void testMissingBuilder() throws JavaModelException {
+ IPath project1Path = env.addProject("P1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ IPath project2Path = env.addProject("P2"); //$NON-NLS-1$
+ env.addExternalJars(project2Path, Util.getJavaClassLibs());
+ env.addRequiredProject(project2Path, project1Path);
+
+ env.addClass(project1Path, "", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class Test {}" //$NON-NLS-1$
+ );
+
+ IPath sub = env.addClass(project2Path, "", "SubTest", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class SubTest extends Test {}" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingNoProblems();
+
+ env.removeRequiredProject(project2Path, project1Path);
+
+ incrementalBuild();
+ expectingOnlySpecificProblemFor(sub, new Problem("", "Test cannot be resolved to a type", sub, 29, 33, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$)
+
+ env.addRequiredProject(project2Path, project1Path);
+
+ try {
+ JavaProject p = (JavaProject) env.getJavaProject(project1Path);
+ p.deconfigure();
+ JavaModelManager.getJavaModelManager().setLastBuiltState(p.getProject(), null);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+
+ env.addClass(project2Path, "", "SubTest", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class SubTest extends Test {}" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ expectingNoProblems();
+ env.removeProject(project1Path);
+ env.removeProject(project2Path);
+}
+
+public void testMissingFieldType() throws JavaModelException {
+ IPath projectPath = env.addProject("Project1"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ IPath root = env.getPackageFragmentRootPath(projectPath, ""); //$NON-NLS-1$
+ env.addClass(root, "p1", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Test {}" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingNoProblems();
+
+ IPath projectPath2 = env.addProject("Project2"); //$NON-NLS-1$
+ env.addExternalJars(projectPath2, Util.getJavaClassLibs());
+ env.addRequiredProject(projectPath2, projectPath);
+ IPath root2 = env.getPackageFragmentRootPath(projectPath2, ""); //$NON-NLS-1$
+ env.addClass(root2, "p2", "Test2", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Test2 {\n" + //$NON-NLS-1$
+ " public static p1.Test field;\n" + //$NON-NLS-1$
+ "}" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ expectingNoProblems();
+
+ IPath projectPath3 = env.addProject("Project3"); //$NON-NLS-1$
+ env.addExternalJars(projectPath3, Util.getJavaClassLibs());
+ env.addRequiredProject(projectPath3, projectPath2);
+ IPath root3 = env.getPackageFragmentRootPath(projectPath3, ""); //$NON-NLS-1$
+ env.addClass(root3, "p3", "Test3", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class Test3 extends p2.Test2 {\n" + //$NON-NLS-1$
+ " static Object field;\n" + //$NON-NLS-1$
+ "}" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ expectingNoProblems();
+ env.removeProject(projectPath);
+}
+
+public void testMissingLibrary1() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ IPath bin = env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ IPath classTest1 = env.addClass(root, "p1", "Test1", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Test1 {}" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingOnlyProblemsFor(new IPath[] {projectPath, classTest1});
+ expectingOnlySpecificProblemsFor(projectPath,
+ new Problem[] {
+ new Problem("", "The project was not built since its build path is incomplete. Cannot find the class file for java.lang.Object. Fix the build path then try building this project", projectPath, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR), //$NON-NLS-1$ //$NON-NLS-2$
+ new Problem("p1", "The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files", classTest1, 0, 1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR) //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ );
+
+ //----------------------------
+ // Step 2
+ //----------------------------
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ incrementalBuild();
+ expectingNoProblems();
+ expectingPresenceOf(new IPath[]{
+ bin.append("p1").append("Test1.class"), //$NON-NLS-1$ //$NON-NLS-2$
+ });
+ env.removeProject(projectPath);
+}
+
+public void testMissingLibrary2() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ IPath bin = env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ IPath classTest1 = env.addClass(root, "p2", "Test1", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Test1 {}" //$NON-NLS-1$
+ );
+ IPath classTest2 = env.addClass(root, "p2", "Test2", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Test2 {}" //$NON-NLS-1$
+ );
+ IPath classTest3 = env.addClass(root, "p3", "Test3", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class Test3 {}" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ env.waitForAutoBuild();
+ expectingSpecificProblemFor(
+ projectPath,
+ new Problem("", "The project was not built since its build path is incomplete. Cannot find the class file for java.lang.Object. Fix the build path then try building this project", projectPath, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ Problem[] prob1 = env.getProblemsFor(classTest1);
+ Problem[] prob2 = env.getProblemsFor(classTest2);
+ Problem[] prob3 = env.getProblemsFor(classTest3);
+ assertEquals("too many problems", prob1.length + prob2.length + prob3.length, 1); //$NON-NLS-1$
+ if(prob1.length == 1) {
+ expectingSpecificProblemFor(classTest1, new Problem("p2", "The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files", classTest1, 0, 1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ } else if (prob2.length == 1) {
+ expectingSpecificProblemFor(classTest2, new Problem("p2", "The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files", classTest2, -1, -1, -1, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ expectingSpecificProblemFor(classTest3, new Problem("p3", "The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files", classTest3, -1, -1, -1, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ //----------------------------
+ // Step 2
+ //----------------------------
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ incrementalBuild();
+ env.waitForAutoBuild();
+ expectingNoProblems();
+ expectingPresenceOf(new IPath[]{
+ bin.append("p2").append("Test1.class"), //$NON-NLS-1$ //$NON-NLS-2$
+ bin.append("p2").append("Test2.class"), //$NON-NLS-1$ //$NON-NLS-2$
+ bin.append("p3").append("Test3.class") //$NON-NLS-1$ //$NON-NLS-2$
+ });
+ env.removeProject(projectPath);
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=172345
+public void testMissingLibrary3() throws JavaModelException {
+ this.abortOnFailure = false; // this test is failing on some releng boxes => do not abort on failures
+ IPath projectPath = env.addProject("Project");
+ IJavaProject project = env.getJavaProject(projectPath);
+ fullBuild();
+ expectingNoProblems();
+ project.setOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, CompilerOptions.WARNING);
+ env.waitForManualRefresh();
+ env.addLibrary(projectPath, projectPath.append("/lib/dummy.jar"), null, null);
+ fullBuild();
+ env.waitForAutoBuild();
+ expectingSpecificProblemFor(
+ projectPath,
+ new Problem("Build path", "Project 'Project' is missing required library: 'lib/dummy.jar'", projectPath, -1, -1, CategorizedProblem.CAT_BUILDPATH,
+ IMarker.SEVERITY_WARNING));
+ project.setOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, CompilerOptions.ERROR);
+ env.waitForManualRefresh();
+ // force classpath change delta - should not have to do this
+ IClasspathEntry[] classpath = project.getRawClasspath();
+ IPath outputLocation;
+ project.setRawClasspath(null, outputLocation = project.getOutputLocation(), false, null);
+ project.setRawClasspath(classpath, outputLocation, false, null);
+ fullBuild();
+ env.waitForAutoBuild();
+ expectingSpecificProblemFor(
+ projectPath,
+ new Problem("", "The project cannot be built until build path errors are resolved", projectPath, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR));
+ expectingSpecificProblemFor(
+ projectPath,
+ new Problem("Build path", "Project 'Project' is missing required library: 'lib/dummy.jar'", projectPath, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR));
+ env.removeProject(projectPath);
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=172345
+public void testMissingLibrary4() throws JavaModelException {
+ this.abortOnFailure = false; // this test is failing on some releng boxes => do not abort on failures
+ IPath projectPath = env.addProject("Project");
+ IJavaProject project = env.getJavaProject(projectPath);
+ fullBuild();
+ expectingNoProblems();
+ env.addLibrary(projectPath, projectPath.append("/lib/dummy.jar"), null, null);
+ env.waitForManualRefresh();
+ fullBuild();
+ env.waitForAutoBuild();
+ expectingSpecificProblemFor(
+ projectPath,
+ new Problem("", "The project cannot be built until build path errors are resolved", projectPath, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR));
+ expectingSpecificProblemFor(
+ projectPath,
+ new Problem("Build path", "Project 'Project' is missing required library: 'lib/dummy.jar'", projectPath, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR));
+ project.setOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, CompilerOptions.WARNING);
+ env.waitForManualRefresh();
+ incrementalBuild();
+ env.waitForManualRefresh();
+ expectingSpecificProblemFor(
+ projectPath,
+ new Problem("Build path", "Project 'Project' is missing required library: 'lib/dummy.jar'", projectPath, -1, -1, CategorizedProblem.CAT_BUILDPATH,
+ IMarker.SEVERITY_WARNING));
+ env.removeProject(projectPath);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=172345
+public void testIncompatibleJdkLEvelOnProject() throws JavaModelException {
+
+ // Create project
+ IPath projectPath = env.addProject("Project");
+ IJavaProject project = env.getJavaProject(projectPath);
+ String[] classlibs = Util.getJavaClassLibs();
+ env.addExternalJars(projectPath, classlibs);
+ Arrays.sort(classlibs);
+
+ // Build it expecting no problem
+ fullBuild();
+ expectingNoProblems();
+
+ // Build incompatible jdk level problem string
+ String projectRuntime = project.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true);
+
+ // Change project incompatible jdk level preferences to warning, perform incremental build and expect 1 problem
+ project.setOption(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, CompilerOptions.WARNING);
+ env.waitForManualRefresh();
+ incrementalBuild();
+ env.waitForAutoBuild();
+ long projectRuntimeJDKLevel = CompilerOptions.versionToJdkLevel(projectRuntime);
+ int max = classlibs.length;
+ List expectedProblems = new ArrayList();
+ for (int i = 0; i < max; i++) {
+ String path = project.getPackageFragmentRoot(classlibs[i]).getPath().makeRelative().toString();
+ Object target = JavaModel.getTarget(new Path(path).makeAbsolute(), true);
+ long libraryJDK = org.eclipse.jdt.internal.core.util.Util.getJdkLevel(target);
+ if (libraryJDK > projectRuntimeJDKLevel) {
+ expectedProblems.add(getJdkLevelProblem(projectRuntime, path, IMarker.SEVERITY_WARNING));
+ }
+ }
+ expectingProblemsFor(projectPath, expectedProblems);
+
+ // Change project incompatible jdk level preferences to error, perform incremental build and expect 2 problems
+ project.setOption(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, CompilerOptions.ERROR);
+ env.waitForManualRefresh();
+ incrementalBuild();
+ env.waitForAutoBuild();
+
+ expectedProblems = new ArrayList();
+ for (int i = 0; i < max; i++) {
+ String path = project.getPackageFragmentRoot(classlibs[i]).getPath().makeRelative().toString();
+ Object target = JavaModel.getTarget(new Path(path).makeAbsolute(), true);
+ long libraryJDK = org.eclipse.jdt.internal.core.util.Util.getJdkLevel(target);
+ if (libraryJDK > projectRuntimeJDKLevel) {
+ expectedProblems.add(getJdkLevelProblem(projectRuntime, path, IMarker.SEVERITY_ERROR));
+ }
+ }
+ expectedProblems.add("Problem : The project cannot be built until build path errors are resolved [ resource : range : <-1,-1> category : <10> severity : <2>]");
+ expectingProblemsFor(projectPath, expectedProblems);
+
+ // Remove project to avoid side effect on other tests
+ env.removeProject(projectPath);
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=172345
+public void testIncompatibleJdkLEvelOnWksp() throws JavaModelException {
+
+ // Save preference
+ JavaModelManager manager = JavaModelManager.getJavaModelManager();
+ IEclipsePreferences preferences = manager.getInstancePreferences();
+ String incompatibleJdkLevel = preferences.get(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, null);
+ try {
+
+ // Create project
+ IPath projectPath = env.addProject("Project");
+ IJavaProject project = env.getJavaProject(projectPath);
+ String[] classlibs = Util.getJavaClassLibs();
+ env.addExternalJars(projectPath, classlibs);
+
+ // Build it expecting no problem
+ fullBuild();
+ env.waitForAutoBuild();
+ expectingNoProblems();
+
+ // Build incompatible jdk level problem string
+ String wkspRuntime = JavaCore.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM);
+ long wkspRuntimeJDKLevel = CompilerOptions.versionToJdkLevel(wkspRuntime);
+ // sort classlibs
+ Arrays.sort(classlibs);
+ // Change workspace incompatible jdk level preferences to warning, perform incremental build and expect 1 problem
+ preferences.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.WARNING);
+ env.waitForManualRefresh();
+ incrementalBuild();
+ env.waitForAutoBuild();
+ List expectedProblems = new ArrayList();
+ int max = classlibs.length;
+ for (int i = 0; i < max; i++) {
+ String path = project.getPackageFragmentRoot(classlibs[i]).getPath().makeRelative().toString();
+ Object target = JavaModel.getTarget(new Path(path).makeAbsolute(), true);
+ long libraryJDK = org.eclipse.jdt.internal.core.util.Util.getJdkLevel(target);
+ if (libraryJDK > wkspRuntimeJDKLevel) {
+ expectedProblems.add(getJdkLevelProblem(wkspRuntime, path, IMarker.SEVERITY_WARNING));
+ }
+ }
+ expectingProblemsFor(projectPath, expectedProblems);
+
+ // Change workspace incompatible jdk level preferences to error, perform incremental build and expect 2 problems
+ preferences.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.ERROR);
+ env.waitForManualRefresh();
+ incrementalBuild();
+ env.waitForAutoBuild();
+ expectedProblems = new ArrayList();
+ for (int i = 0; i < max; i++) {
+ String path = project.getPackageFragmentRoot(classlibs[i]).getPath().makeRelative().toString();
+ Object target = JavaModel.getTarget(new Path(path).makeAbsolute(), true);
+ long libraryJDK = org.eclipse.jdt.internal.core.util.Util.getJdkLevel(target);
+ if (libraryJDK > wkspRuntimeJDKLevel) {
+ expectedProblems.add(getJdkLevelProblem(wkspRuntime, path, IMarker.SEVERITY_ERROR));
+ }
+ }
+ expectedProblems.add("Problem : The project cannot be built until build path errors are resolved [ resource : range : <-1,-1> category : <10> severity : <2>]");
+ expectingProblemsFor(projectPath, expectedProblems);
+
+ // Remove project to avoid side effect on other tests
+ env.removeProject(projectPath);
+ } finally {
+ // Put back workspace preferences same as before running the test
+ if (incompatibleJdkLevel == null) {
+ preferences.remove(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL);
+ } else {
+ preferences.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, incompatibleJdkLevel);
+ }
+ }
+}
+
+public void testMissingProject() throws JavaModelException {
+ IPath project1Path = env.addProject("MP1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ IPath project2Path = env.addProject("MP2"); //$NON-NLS-1$
+ env.addExternalJars(project2Path, Util.getJavaClassLibs());
+ env.addRequiredProject(project2Path, project1Path);
+
+ fullBuild();
+ expectingNoProblems();
+
+ //----------------------------
+ // Step 2
+ //----------------------------
+ env.removeProject(project1Path);
+
+ incrementalBuild();
+ env.waitForAutoBuild();
+ expectingOnlyProblemsFor(project2Path);
+ expectingOnlySpecificProblemsFor(project2Path,
+ new Problem[] {
+ new Problem("", "The project cannot be built until build path errors are resolved", project2Path, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR), //$NON-NLS-1$ //$NON-NLS-2$
+ new Problem("Build path", "Project 'MP2' is missing required Java project: 'MP1'", project2Path, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR) //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ );
+
+ project1Path = env.addProject("MP1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ incrementalBuild();
+ env.waitForAutoBuild();
+ expectingNoProblems();
+
+ //----------------------------
+ // Step 3
+ //----------------------------
+ Hashtable options = JavaCore.getOptions();
+ options.put(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, JavaCore.IGNORE);
+ JavaCore.setOptions(options);
+ env.waitForManualRefresh();
+ env.removeProject(project1Path);
+
+ incrementalBuild();
+ env.waitForAutoBuild();
+ expectingOnlyProblemsFor(project2Path);
+ expectingOnlySpecificProblemFor(project2Path,
+ new Problem("Build path", "Project 'MP2' is missing required Java project: 'MP1'", project2Path, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR) //$NON-NLS-1$ //$NON-NLS-2$
+ );
+
+ project1Path = env.addProject("MP1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ incrementalBuild();
+ env.waitForAutoBuild();
+ expectingNoProblems();
+ env.removeProject(project1Path);
+ env.removeProject(project2Path);
+}
+
+public void testMissingOptionalProject() throws JavaModelException {
+ IPath project1Path = env.addProject("MP1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ IPath project2Path = env.addProject("MP2"); //$NON-NLS-1$
+ env.addExternalJars(project2Path, Util.getJavaClassLibs());
+ env.addRequiredProject(project2Path, project1Path, true/*optional*/);
+
+ fullBuild();
+ expectingNoProblems();
+
+ //----------------------------
+ // Step 2
+ //----------------------------
+ env.removeProject(project1Path);
+
+ incrementalBuild();
+ expectingNoProblems();
+
+ project1Path = env.addProject("MP1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ incrementalBuild();
+ expectingNoProblems();
+
+ //----------------------------
+ // Step 3
+ //----------------------------
+ Hashtable options = JavaCore.getOptions();
+ options.put(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, JavaCore.IGNORE);
+ JavaCore.setOptions(options);
+ env.waitForManualRefresh();
+ env.removeProject(project1Path);
+
+ incrementalBuild();
+ env.waitForAutoBuild();
+ expectingNoProblems();
+
+ project1Path = env.addProject("MP1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ incrementalBuild();
+ expectingNoProblems();
+ env.removeProject(project1Path);
+ env.removeProject(project2Path);
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=160132
+public void test0100() throws JavaModelException {
+ if (!AbstractCompilerTest.isJRELevel(AbstractCompilerTest.F_1_5)) {
+ // expected to run only in 1.5 mode on top of a jre 1.5 or above
+ return;
+ }
+ IPath projectPath = env.addProject("P", "1.5");
+ IPath defaultPackagePath = env.addPackage(projectPath, "");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.addClass(defaultPackagePath, "X",
+ "public interface X {\n" +
+ " interface Entry {\n" +
+ " interface Internal extends Entry {\n" +
+ " Internal createEntry();\n" +
+ " }\n" +
+ " }\n" +
+ "}"
+ );
+ fullBuild();
+ expectingNoProblems();
+ env.addClass(defaultPackagePath, "Y",
+ "public class Y implements X.Entry.Internal {\n" +
+ " public Internal createEntry() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}");
+ incrementalBuild();
+ expectingNoProblems();
+ env.removeProject(projectPath);
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=143025
+public void testMissingOutputFolder() throws JavaModelException {
+ IPath projectPath = env.addProject("P"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ IPath bin = env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ fullBuild();
+ expectingNoProblems();
+
+ env.removeFolder(bin);
+
+ incrementalBuild();
+ expectingNoProblems();
+ expectingPresenceOf(bin); // check that bin folder was recreated and is marked as derived
+ if (!env.getProject(projectPath).getFolder("bin").isDerived())
+ fail("output folder is not derived");
+ env.removeProject(projectPath);
+}
+@Override
+protected void tearDown() throws Exception {
+ super.tearDown();
+}
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/CopyResourceTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/CopyResourceTests.java
new file mode 100644
index 0000000000..58d2a067f3
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/CopyResourceTests.java
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import junit.framework.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.tests.util.Util;
+
+/**
+ * Basic tests of the image builder.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class CopyResourceTests extends BuilderTests {
+
+ public CopyResourceTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(CopyResourceTests.class);
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=117302
+ public void testFilteredResources() throws JavaModelException {
+ IPath projectPath = env.addProject("P"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath src = env.addPackageFragmentRoot(
+ projectPath,
+ "", //$NON-NLS-1$
+ new IPath[] {new org.eclipse.core.runtime.Path("foo/;bar/")}, //$NON-NLS-1$
+ new IPath[] {new org.eclipse.core.runtime.Path("foo/ignored/")}, //$NON-NLS-1$
+ "bin"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ env.addClass(src, "foo", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package foo;"+ //$NON-NLS-1$
+ "public class A extends bar.B {}" //$NON-NLS-1$
+ );
+ env.addClass(src, "bar", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package bar;"+ //$NON-NLS-1$
+ "public class B {}" //$NON-NLS-1$
+ );
+ env.addFolder(src, "foo/skip"); //$NON-NLS-1$
+ IPath ignored = env.addFolder(src, "foo/ignored"); //$NON-NLS-1$
+ env.addFile(ignored, "test.txt", "test file"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ env.addFile(src.append("bar"), "test.txt", "test file"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+ org.eclipse.jdt.core.IJavaProject p = env.getJavaProject("P");
+ java.util.Map options = p.getOptions(true);
+ options.put(org.eclipse.jdt.core.JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "bar*"); //$NON-NLS-1$
+ options.put(org.eclipse.jdt.core.JavaCore.CORE_JAVA_BUILD_RECREATE_MODIFIED_CLASS_FILES_IN_OUTPUT_FOLDER, "enabled"); //$NON-NLS-1$
+ p.setOptions(options);
+
+ int max = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
+ try {
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 1;
+ fullBuild();
+ expectingNoProblems();
+ expectingNoPresenceOf(projectPath.append("bin/foo/skip/")); //$NON-NLS-1$
+ expectingNoPresenceOf(projectPath.append("bin/foo/ignored/")); //$NON-NLS-1$
+ expectingNoPresenceOf(projectPath.append("bin/bar/test.txt")); //$NON-NLS-1$
+
+ env.removeFolder(projectPath.append("bin/bar")); //$NON-NLS-1$
+ env.addClass(src, "x", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package x;"+ //$NON-NLS-1$
+ "public class A extends bar.B {}" //$NON-NLS-1$
+ );
+ env.addFile(src.append("bar"), "test.txt", "changed test file"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ incrementalBuild();
+ expectingNoProblems();
+ expectingNoPresenceOf(projectPath.append("bin/foo/skip/")); //$NON-NLS-1$
+ expectingNoPresenceOf(projectPath.append("bin/foo/ignored/")); //$NON-NLS-1$
+ expectingNoPresenceOf(projectPath.append("bin/bar/test.txt")); //$NON-NLS-1$
+ } finally {
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = max;
+ }
+ }
+
+ public void testSimpleProject() throws JavaModelException {
+ IPath projectPath = env.addProject("P1"); //$NON-NLS-1$
+ IPath src = env.getPackageFragmentRootPath(projectPath, ""); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, ""); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ env.addFile(src, "z.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fullBuild();
+ expectingNoProblems();
+ expectingPresenceOf(projectPath.append("z.txt")); //$NON-NLS-1$
+
+ env.removeFile(src.append("z.txt")); //$NON-NLS-1$
+ IPath p = env.addFolder(src, "p"); //$NON-NLS-1$
+ env.addFile(p, "p.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ incrementalBuild();
+ expectingNoProblems();
+ expectingNoPresenceOf(projectPath.append("z.txt")); //$NON-NLS-1$
+ expectingPresenceOf(p.append("p.txt")); //$NON-NLS-1$
+ }
+
+ public void testProjectWithBin() throws JavaModelException {
+ IPath projectPath = env.addProject("P2"); //$NON-NLS-1$
+ IPath src = env.getPackageFragmentRootPath(projectPath, ""); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ env.addFile(src, "z.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fullBuild();
+ expectingNoProblems();
+ expectingPresenceOf(new IPath[] {
+ projectPath.append("z.txt"), //$NON-NLS-1$
+ projectPath.append("bin/z.txt") //$NON-NLS-1$
+ });
+
+ env.removeFile(src.append("z.txt")); //$NON-NLS-1$
+ IPath p = env.addFolder(src, "p"); //$NON-NLS-1$
+ env.addFile(p, "p.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ incrementalBuild();
+ expectingNoProblems();
+ expectingNoPresenceOf(new IPath[] {
+ projectPath.append("z.txt"), //$NON-NLS-1$
+ projectPath.append("bin/z.txt") //$NON-NLS-1$
+ });
+ expectingPresenceOf(new IPath[] {
+ projectPath.append("p/p.txt"), //$NON-NLS-1$
+ projectPath.append("bin/p/p.txt") //$NON-NLS-1$
+ });
+ }
+
+ public void testProjectWithSrcBin() throws JavaModelException {
+ IPath projectPath = env.addProject("P3"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath src = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ env.addFile(src, "z.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fullBuild();
+ expectingNoProblems();
+ expectingPresenceOf(new IPath[] {
+ projectPath.append("src/z.txt"), //$NON-NLS-1$
+ projectPath.append("bin/z.txt") //$NON-NLS-1$
+ });
+
+ env.removeFile(src.append("z.txt")); //$NON-NLS-1$
+ env.addFile(src, "zz.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ incrementalBuild();
+ expectingNoProblems();
+ expectingNoPresenceOf(new IPath[] {
+ projectPath.append("src/z.txt"), //$NON-NLS-1$
+ projectPath.append("bin/z.txt") //$NON-NLS-1$
+ });
+ expectingPresenceOf(new IPath[] {
+ projectPath.append("src/zz.txt"), //$NON-NLS-1$
+ projectPath.append("bin/zz.txt") //$NON-NLS-1$
+ });
+ }
+
+ public void testProjectWith2SrcBin() throws JavaModelException {
+ IPath projectPath = env.addProject("P4"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath src1 = env.addPackageFragmentRoot(projectPath, "src1"); //$NON-NLS-1$
+ IPath src2 = env.addPackageFragmentRoot(projectPath, "src2"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ env.addFile(src1, "z.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ env.addFile(src2, "zz.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fullBuild();
+ expectingNoProblems();
+ expectingPresenceOf(new IPath[] {
+ projectPath.append("src1/z.txt"), //$NON-NLS-1$
+ projectPath.append("bin/z.txt"), //$NON-NLS-1$
+ projectPath.append("src2/zz.txt"), //$NON-NLS-1$
+ projectPath.append("bin/zz.txt") //$NON-NLS-1$
+ });
+
+ env.removeFile(src2.append("zz.txt")); //$NON-NLS-1$
+ IPath p = env.addFolder(src2, "p"); //$NON-NLS-1$
+ env.addFile(p, "p.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ incrementalBuild();
+ expectingNoProblems();
+ expectingNoPresenceOf(new IPath[] {
+ projectPath.append("src2/zz.txt"), //$NON-NLS-1$
+ projectPath.append("bin/zz.txt") //$NON-NLS-1$
+ });
+ expectingPresenceOf(new IPath[] {
+ projectPath.append("src2/p/p.txt"), //$NON-NLS-1$
+ projectPath.append("bin/p/p.txt") //$NON-NLS-1$
+ });
+ }
+
+ public void testProjectWith2SrcAsBin() throws JavaModelException {
+ IPath projectPath = env.addProject("P5"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath src1 = env.addPackageFragmentRoot(projectPath, "src1", null, "src1"); //$NON-NLS-1$ //$NON-NLS-2$
+ IPath src2 = env.addPackageFragmentRoot(projectPath, "src2", null, "src2"); //$NON-NLS-1$ //$NON-NLS-2$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ env.addFile(src1, "z.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ env.addFile(src2, "zz.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fullBuild();
+ expectingNoProblems();
+ expectingPresenceOf(new IPath[] {
+ projectPath.append("src1/z.txt"), //$NON-NLS-1$
+ projectPath.append("src2/zz.txt"), //$NON-NLS-1$
+ });
+ expectingNoPresenceOf(new IPath[] {
+ projectPath.append("src2/z.txt"), //$NON-NLS-1$
+ projectPath.append("bin") //$NON-NLS-1$
+ });
+ }
+
+ public void testProjectWith2Src2Bin() throws JavaModelException {
+ IPath projectPath = env.addProject("P6"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath src1 = env.addPackageFragmentRoot(projectPath, "src1", null, "bin1"); //$NON-NLS-1$ //$NON-NLS-2$
+ IPath src2 = env.addPackageFragmentRoot(projectPath, "src2", null, "bin2"); //$NON-NLS-1$ //$NON-NLS-2$
+ env.setOutputFolder(projectPath, "bin1"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ env.addFile(src1, "z.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ env.addFile(src2, "zz.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fullBuild();
+ expectingNoProblems();
+ expectingPresenceOf(new IPath[] {
+ projectPath.append("bin1/z.txt"), //$NON-NLS-1$
+ projectPath.append("bin2/zz.txt"), //$NON-NLS-1$
+ });
+ expectingNoPresenceOf(new IPath[] {
+ projectPath.append("bin1/zz.txt"), //$NON-NLS-1$
+ projectPath.append("bin2/z.txt"), //$NON-NLS-1$
+ });
+ }
+
+ public void test2ProjectWith1Bin() throws JavaModelException {
+ IPath projectPath = env.addProject("P7"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ IPath bin = env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ IPath projectPath2 = env.addProject("P8"); //$NON-NLS-1$
+ IPath binLocation = env.getProject(projectPath).getFolder("bin").getLocation(); //$NON-NLS-1$
+ env.setExternalOutputFolder(projectPath2, "externalBin", binLocation); //$NON-NLS-1$
+ env.addExternalJars(projectPath2, Util.getJavaClassLibs());
+
+ env.addFile(projectPath2, "z.txt", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fullBuild();
+ expectingNoProblems();
+ expectingPresenceOf(bin.append("z.txt")); //$NON-NLS-1$
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=154693
+ public void testBug154693() throws JavaModelException {
+ IPath projectPath = env.addProject("P9"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath src = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ org.eclipse.jdt.core.IJavaProject p = env.getJavaProject("P9");
+ java.util.Map options = p.getOptions(true);
+ options.put(org.eclipse.jdt.core.JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ".svn/"); //$NON-NLS-1$
+ p.setOptions(options);
+
+ IPath folder = env.addFolder(src, "p");
+ env.addFolder(folder, ".svn");
+ env.addFile(folder, "A.java", "package p;\nclass A{}"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ fullBuild();
+ expectingNoProblems();
+ expectingNoPresenceOf(new IPath[] {
+ projectPath.append("bin/p/.svn") //$NON-NLS-1$
+ });
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=194420
+ public void testBug194420() throws JavaModelException {
+ IPath projectPath = env.addProject("P"); //$NON-NLS-1$
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath src = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ IPath bin = env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ IPath folder = env.addFolder(src, "p");
+ String testContents = "incremental test contents"; //$NON-NLS-1$
+ IPath zPath = env.addFile(folder, "z.txt", testContents); //$NON-NLS-1$
+ IPath zBinPath = bin.append("p/z.txt");
+ org.eclipse.core.resources.IFile zFile = env.getWorkspace().getRoot().getFile(zPath);
+
+ fullBuild();
+ expectingNoProblems();
+ expectingPresenceOf(zBinPath);
+ try {
+ byte[] contents = new byte[testContents.length()];
+ java.io.InputStream stream = zFile.getContents();
+ stream.read(contents);
+ stream.close();
+ assumeEquals("File was not copied", testContents, new String(contents)); //$NON-NLS-1$
+ } catch (Exception e) {
+ fail("File was not copied"); //$NON-NLS-1$
+ }
+
+ java.io.File file = new java.io.File(zFile.getLocation().toOSString());
+ file.delete();
+
+ fullBuild();
+ expectingNoProblems();
+ expectingNoPresenceOf(zBinPath);
+
+ testContents = "incremental test contents"; //$NON-NLS-1$
+ env.addFile(folder, "z.txt", testContents); //$NON-NLS-1$
+
+ incrementalBuild();
+ expectingNoProblems();
+ expectingPresenceOf(zBinPath);
+ try {
+ byte[] contents = new byte[testContents.length()];
+ java.io.InputStream stream = zFile.getContents();
+ stream.read(contents);
+ stream.close();
+ assumeEquals("File was not copied", testContents, new String(contents)); //$NON-NLS-1$
+ } catch (Exception e) {
+ fail("File was not copied"); //$NON-NLS-1$
+ }
+
+ env.addFile(folder, "z.txt", "about to be deleted"); //$NON-NLS-1$ //$NON-NLS-2$
+ file.delete();
+
+ incrementalBuild();
+ expectingNoProblems();
+ expectingNoPresenceOf(zBinPath);
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/DependencyTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/DependencyTests.java
new file mode 100644
index 0000000000..126c106ec0
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/DependencyTests.java
@@ -0,0 +1,1258 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import junit.framework.Test;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
+import org.eclipse.jdt.core.tests.util.Util;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class DependencyTests extends BuilderTests {
+ public DependencyTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(DependencyTests.class);
+ }
+
+ public void testAbstractMethod() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Indicted", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public abstract class Indicted {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath collaboratorPath = env.addClass(root, "p2", "Collaborator", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Collaborator extends Indicted{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "Indicted", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public abstract class Indicted {\n"+ //$NON-NLS-1$
+ " public abstract void foo();\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(collaboratorPath);
+ expectingOnlySpecificProblemFor(collaboratorPath, new Problem("Collaborator", "The type Collaborator must implement the inherited abstract method Indicted.foo()", collaboratorPath, 38, 50, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=168208
+ public void testCaseInvariantType() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ org.eclipse.jdt.core.IJavaProject p = env.getJavaProject("Project");
+ java.util.Map options = p.getOptions(true);
+ options.put(org.eclipse.jdt.core.JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, org.eclipse.jdt.core.JavaCore.DISABLED); //$NON-NLS-1$
+ p.setOptions(options);
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n" +
+ " class Node {}\n" +
+ "}" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p1", "Bb", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "class Bb {}" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n" +
+ " class node {}\n" +
+ "}" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p1", "Bb", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "class BB {}" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testExactMethodDeleting() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i(int i) {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath cPath = env.addClass(root, "p3", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class C extends p2.B{\n"+ //$NON-NLS-1$
+ " int j = i(1);\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath dPath = env.addClass(root, "p3", "D", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class D extends p2.B{\n"+ //$NON-NLS-1$
+ " public class M {\n"+ //$NON-NLS-1$
+ " int j = i(1);\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath xPath = env.addClass(root, "p4", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p4;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " int foo(p3.C c) { return c.i(1); }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {cPath, dPath, xPath});
+ expectingSpecificProblemFor(cPath, new Problem("C", "The method i(int) is undefined for the type C", cPath, 50, 51, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(dPath, new Problem("D", "The method i(int) is undefined for the type D.M", dPath, 69, 70, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(xPath, new Problem("X", "The method i(int) is undefined for the type C", xPath, 57, 58, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ " protected int i(long l) throws Exception {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {cPath, dPath, xPath});
+ expectingSpecificProblemFor(cPath, new Problem("C", "Default constructor cannot handle exception type Exception thrown by implicit super constructor. Must define an explicit constructor", cPath, 50, 54, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(dPath, new Problem("D", "Default constructor cannot handle exception type Exception thrown by implicit super constructor. Must define an explicit constructor", dPath, 69, 73, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(xPath, new Problem("X", "The method i(long) from the type B is not visible", xPath, 57, 58, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i(int i) {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testExactMethodVisibility() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i() {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath cPath = env.addClass(root, "p3", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class C extends p2.B{\n"+ //$NON-NLS-1$
+ " int j = i();\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath dPath = env.addClass(root, "p3", "D", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class D extends p2.B{\n"+ //$NON-NLS-1$
+ " public class M {\n"+ //$NON-NLS-1$
+ " int j = i();\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath xPath = env.addClass(root, "p4", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p4;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " int foo(p3.C c) { return c.i(); }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " int i() {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {cPath, dPath, xPath});
+ expectingSpecificProblemFor(cPath, new Problem("C", "The method i() from the type A is not visible", cPath, 50, 51, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(dPath, new Problem("D", "The method i() from the type A is not visible", dPath, 69, 70, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(xPath, new Problem("X", "The method i() from the type A is not visible", xPath, 57, 58, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " protected int i() {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {xPath});
+ expectingSpecificProblemFor(xPath, new Problem("X", "The method i() from the type A is not visible", xPath, 57, 58, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i() {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testExternalJarChanged() throws CoreException, java.io.IOException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ IPath root = env.getPackageFragmentRootPath(projectPath, ""); //$NON-NLS-1$
+ IPath classTest = env.addClass(root, "p", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;\n"+ //$NON-NLS-1$
+ "public class X {\n" + //$NON-NLS-1$
+ " void foo() {\n" + //$NON-NLS-1$
+ " new q.Y().bar();\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}" //$NON-NLS-1$
+ );
+ String externalJar = Util.getOutputDirectory() + java.io.File.separator + "test.jar"; //$NON-NLS-1$
+ Util.createJar(
+ new String[] {
+ "q/Y.java", //$NON-NLS-1$
+ "package q;\n" + //$NON-NLS-1$
+ "public class Y {\n" + //$NON-NLS-1$
+ "}" //$NON-NLS-1$
+ },
+ new java.util.HashMap(),
+ externalJar
+ );
+ env.addExternalJar(projectPath, externalJar);
+
+ // build -> expecting problems
+ fullBuild();
+ expectingProblemsFor(
+ classTest,
+ "Problem : The method bar() is undefined for the type Y [ resource : range : <57,60> category : <50> severity : <2>]"
+ );
+
+ // fix jar
+ Util.createJar(
+ new String[] {
+ "q/Y.java", //$NON-NLS-1$
+ "package q;\n" + //$NON-NLS-1$
+ "public class Y {\n" + //$NON-NLS-1$
+ " public void bar() {\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}" //$NON-NLS-1$
+ },
+ new java.util.HashMap(),
+ externalJar
+ );
+ // add new class to trigger an incremental build
+ env.getProject(projectPath).touch(null);
+
+ // incremental build should notice jar file has changed & do a full build
+ incrementalBuild();
+ expectingNoProblems();
+ }
+
+ public void testFieldDeleting() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i;\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath cPath = env.addClass(root, "p3", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class C extends p2.B{\n"+ //$NON-NLS-1$
+ " int j = i;\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath xPath = env.addClass(root, "p4", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p4;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " int foo(p3.C c) { return c.i; }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {cPath, xPath});
+ expectingSpecificProblemFor(cPath, new Problem("C", "i cannot be resolved to a variable", cPath, 50, 51, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(xPath, new Problem("X", "i cannot be resolved or is not a field", xPath, 57, 58, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i;\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testFieldVisibility() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i;\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath cPath = env.addClass(root, "p3", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class C extends p2.B{\n"+ //$NON-NLS-1$
+ " int j = i;\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath xPath = env.addClass(root, "p4", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p4;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " int foo(p3.C c) { return c.i; }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " int i;\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {cPath, xPath});
+ expectingSpecificProblemFor(cPath, new Problem("C", "The field A.i is not visible", cPath, 50, 51, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(xPath, new Problem("X", "The field A.i is not visible", xPath, 57, 58, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " protected int i;\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {xPath});
+ expectingSpecificProblemFor(xPath, new Problem("X", "The field A.i is not visible", xPath, 57, 58, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i;\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ // 77272
+ public void testInterfaceDeleting() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Vehicle", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public interface Vehicle {}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p1", "Car", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public interface Car extends Vehicle {}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p1", "CarImpl", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class CarImpl implements Car {}\n" //$NON-NLS-1$
+ );
+
+ IPath testPath = env.addClass(root, "p1", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Test { public Vehicle createVehicle() { return new CarImpl(); } }\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "Car", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public interface Car {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(testPath);
+ expectingSpecificProblemFor(testPath, new Problem("Test", "Type mismatch: cannot convert from CarImpl to Vehicle", testPath, 72, 85, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "Car", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public interface Car extends Vehicle {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testMemberTypeDeleting() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public class M { public int i; };\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath cPath = env.addClass(root, "p3", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class C extends p2.B{\n"+ //$NON-NLS-1$
+ " M m;\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath xPath = env.addClass(root, "p4", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p4;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " int foo(p3.C.M m) { return m.i; }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {cPath, xPath});
+ expectingSpecificProblemFor(cPath, new Problem("C", "M cannot be resolved to a type", cPath, 42, 43, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(xPath, new Problem("X", "p3.C.M cannot be resolved to a type", xPath, 38, 44, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public class M { public int i; };\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testMemberTypeVisibility() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public class M { public int i; };\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath cPath = env.addClass(root, "p3", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class C extends p2.B{\n"+ //$NON-NLS-1$
+ " M m;\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath xPath = env.addClass(root, "p4", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p4;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " int foo(p3.C.M m) { return m.i; }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " class M { public int i; };\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {cPath, xPath});
+ expectingSpecificProblemFor(cPath, new Problem("C", "The type M is not visible", cPath, 42, 43, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(xPath, new Problem("X", "The type p3.C.M is not visible", xPath, 38, 44, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " protected class M { public int i; };\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {xPath});
+ expectingSpecificProblemFor(xPath, new Problem("X", "The type p3.C.M is not visible", xPath, 38, 44, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public class M { public int i; };\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testMethodDeleting() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i(A a) {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath cPath = env.addClass(root, "p3", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class C extends p2.B{\n"+ //$NON-NLS-1$
+ " int j = i(this);\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath dPath = env.addClass(root, "p3", "D", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class D extends p2.B{\n"+ //$NON-NLS-1$
+ " public class M {\n"+ //$NON-NLS-1$
+ " int j = i(new D());\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath xPath = env.addClass(root, "p4", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p4;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " int foo(p3.C c) { return c.i(c); }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {cPath, dPath, xPath});
+ expectingSpecificProblemFor(cPath, new Problem("C", "The method i(C) is undefined for the type C", cPath, 50, 51, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(dPath, new Problem("D", "The method i(D) is undefined for the type D.M", dPath, 69, 70, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(xPath, new Problem("X", "The method i(C) is undefined for the type C", xPath, 57, 58, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ " public int i(B b) {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i(A a) {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testMethodVisibility() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i(A a) {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath cPath = env.addClass(root, "p3", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class C extends p2.B{\n"+ //$NON-NLS-1$
+ " int j = i(this);\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath dPath = env.addClass(root, "p3", "D", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class D extends p2.B{\n"+ //$NON-NLS-1$
+ " public class M {\n"+ //$NON-NLS-1$
+ " int j = i(new D());\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath xPath = env.addClass(root, "p4", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p4;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " int foo(p3.C c) { return c.i(c); }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " int i(A a) {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {cPath, dPath, xPath});
+ expectingSpecificProblemFor(cPath, new Problem("C", "The method i(A) from the type A is not visible", cPath, 50, 51, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(dPath, new Problem("D", "The method i(A) from the type A is not visible", dPath, 69, 70, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(xPath, new Problem("X", "The method i(A) from the type A is not visible", xPath, 57, 58, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ " protected int i(B b) {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {xPath});
+ expectingSpecificProblemFor(xPath, new Problem("X", "The method i(B) from the type B is not visible", xPath, 57, 58, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public int i(A a) {return 1;};\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class B extends A{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testMissingClassFile() throws JavaModelException {
+ IPath project1Path = env.addProject("Project1"); //$NON-NLS-1$
+ env.addExternalJars(project1Path, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(project1Path,""); //$NON-NLS-1$
+
+ IPath root1 = env.addPackageFragmentRoot(project1Path, "src"); //$NON-NLS-1$
+ env.setOutputFolder(project1Path, "bin"); //$NON-NLS-1$
+
+ env.addClass(root1, "p1", "MissingClass", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class MissingClass {}" //$NON-NLS-1$
+ );
+
+ IPath project2Path = env.addProject("Project2"); //$NON-NLS-1$
+ env.addExternalJars(project2Path, Util.getJavaClassLibs());
+ env.addRequiredProject(project2Path, project1Path);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(project2Path,""); //$NON-NLS-1$
+
+ IPath root2 = env.addPackageFragmentRoot(project2Path, "src"); //$NON-NLS-1$
+ env.setOutputFolder(project2Path, "bin"); //$NON-NLS-1$
+
+ env.addClass(root2, "p2", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.MissingClass;\n" +
+ "public class A {\n"+ //$NON-NLS-1$
+ " public void foo(MissingClass data) {}\n"+ //$NON-NLS-1$
+ " public void foo(String data) {}\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath project3Path = env.addProject("Project3"); //$NON-NLS-1$
+ env.addExternalJars(project3Path, Util.getJavaClassLibs());
+ env.addRequiredProject(project3Path, project2Path);
+ // missing required Project1 so MissingClass cannot be found
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(project3Path,""); //$NON-NLS-1$
+
+ IPath root3 = env.addPackageFragmentRoot(project3Path, "src"); //$NON-NLS-1$
+ env.setOutputFolder(project3Path, "bin"); //$NON-NLS-1$
+
+ IPath bPath = env.addClass(root3, "p3", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "import p2.A;\n" +
+ "public class B {\n"+ //$NON-NLS-1$
+ " public static void main(String[] args) {\n" + //$NON-NLS-1$
+ " new A().foo(new String());\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingOnlyProblemsFor(new IPath[] {project3Path, bPath});
+ expectingSpecificProblemFor(project3Path, new Problem("Project3", "The project was not built since its build path is incomplete. Cannot find the class file for p1.MissingClass. Fix the build path then try building this project", project3Path, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(bPath, new Problem("B", "The type p1.MissingClass cannot be resolved. It is indirectly referenced from required .class files", bPath, 86, 111, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root2, "p2", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class A {\n"+ //$NON-NLS-1$
+ " public void foo(String data) {}\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ expectingNoProblems();
+ }
+
+ // 181269
+ public void testSecondaryTypeDeleting() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A extends Secondary {}\n"+ //$NON-NLS-1$
+ "class Secondary {}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ IPath typePath = env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A extends Secondary {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(typePath, new Problem("A", "Secondary cannot be resolved to a type", typePath, 35, 44, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ // 72468
+ public void testTypeDeleting() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {}\n" //$NON-NLS-1$
+ );
+
+ IPath bPath = env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class B extends p1.A{}\n" //$NON-NLS-1$
+ );
+
+ IPath cPath = env.addClass(root, "p3", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class C extends p2.B{}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "class Deleted {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {bPath, cPath});
+ expectingSpecificProblemFor(bPath, new Problem("B", "p1.A cannot be resolved to a type", bPath, 35, 39, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(cPath, new Problem("C", "The hierarchy of the type C is inconsistent", cPath, 25, 26, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class B {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ // 72468
+ public void testTypeVisibility() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {}\n" //$NON-NLS-1$
+ );
+
+ IPath bPath = env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class B extends p1.A{}\n" //$NON-NLS-1$
+ );
+
+ IPath cPath = env.addClass(root, "p3", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p3;\n"+ //$NON-NLS-1$
+ "public class C extends p2.B{}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "class A {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {bPath, cPath});
+ expectingSpecificProblemFor(bPath, new Problem("B", "The type p1.A is not visible", bPath, 35, 39, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(cPath, new Problem("C", "The hierarchy of the type C is inconsistent", cPath, 25, 26, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class B {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class B extends p1.A{}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {bPath, cPath});
+ expectingSpecificProblemFor(bPath, new Problem("B", "The type p1.A is not visible", bPath, 35, 39, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(cPath, new Problem("C", "The hierarchy of the type C is inconsistent", cPath, 25, 26, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ // 79163
+ public void testTypeVisibility2() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath aPath = env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {\n" + //$NON-NLS-1$
+ " void foo() { p2.FooFactory.createFoo().foo(); }\n" + //$NON-NLS-1$
+ " void foos() { p2.FooFactory.createFoos().clone(); }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ // Foo & Foos are not public to get visibility problems
+ env.addClass(root, "p2", "Foo", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "class Foo { public void foo() {} }\n" //$NON-NLS-1$
+ );
+ env.addClass(root, "p2", "Foos", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "class Foos {}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "FooFactory", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class FooFactory {\n" + //$NON-NLS-1$
+ " public static Foo createFoo() { return null; }\n" + //$NON-NLS-1$
+ " public static Foos[] createFoos() { return null; }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {aPath});
+ expectingSpecificProblemFor(aPath, new Problem("A", "The type Foo is not visible", aPath, 43, 68, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(aPath, new Problem("A", "The type Foos is not visible", aPath, 93, 119, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p2", "Foo", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Foo { public void foo() {} }\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {aPath});
+ expectingSpecificProblemFor(aPath, new Problem("A", "The type Foos is not visible", aPath, 93, 119, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p2", "Foos", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Foos { }\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p2", "Foo", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "class Foo { public void foo() {} }\n" //$NON-NLS-1$
+ );
+ env.addClass(root, "p2", "Foos", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "class Foos {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {aPath});
+ expectingSpecificProblemFor(aPath, new Problem("A", "The type Foo is not visible", aPath, 43, 68, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(aPath, new Problem("A", "The type Foos is not visible", aPath, 93, 119, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ public void testTypeVariable() throws JavaModelException {
+ if ((AbstractCompilerTest.getPossibleComplianceLevels() & AbstractCompilerTest.F_1_5) == 0) return;
+
+ IPath projectPath = env.addProject("Project", "1.5"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {}\n" //$NON-NLS-1$
+ );
+
+ IPath bPath = env.addClass(root, "p2", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class B extends p1.A {}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ IPath aPath = env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {bPath});
+ expectingSpecificProblemFor(bPath, new Problem("B", "The type A is not generic; it cannot be parameterized with arguments ", bPath, 38, 42, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {aPath, bPath});
+ expectingSpecificProblemFor(bPath, new Problem("B", "Bound mismatch: The type T is not a valid substitute for the bounded parameter of the type A", bPath, 43, 44, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(aPath, new Problem("A", "Comparable is a raw type. References to generic type Comparable should be parameterized", aPath, 37, 47, CategorizedProblem.CAT_UNCHECKED_RAW, IMarker.SEVERITY_WARNING)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class A {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=159709
+// Full build and incremental build behave differently for deprecation
+// warnings, which is unexpected. Guard test for DeprecatedTest#test015 (the
+// builder is not the cause of the bug, but we want to ensure that the end to
+// end behavior is OK).
+public void test0100() throws JavaModelException {
+ IPath projectPath = env.addProject("P");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ IPath rootPath = env.getPackageFragmentRootPath(projectPath, "");
+ env.addClass(rootPath, "a", "N1",
+ "package a;\n" +
+ "public class N1 {\n" +
+ " public void foo() {}\n" +
+ " /** @deprecated */\n" +
+ " public class N2 {" +
+ " public void foo() {}" +
+ " public class N3 {" +
+ " public void foo() {}" +
+ " }" +
+ " }" +
+ " void bar() {}\n" +
+ "}\n"
+ );
+ String M1Contents =
+ "package p;\n" +
+ "public class M1 {\n" +
+ " public void foo() {}\n" +
+ " /** @deprecated */\n" +
+ " public class M2 {" +
+ " public void foo() {}" +
+ " public class M3 {" +
+ " public void foo() {}" +
+ " }" +
+ " }" +
+ " void bar() {\n" +
+ " a.N1.N2.N3 m = null;\n" +
+ " m.foo();\n" +
+ " }\n" +
+ "}\n";
+ IPath M1Path = env.addClass(rootPath, "p", "M1", M1Contents);
+ fullBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {M1Path});
+ expectingSpecificProblemFor(M1Path,
+ new Problem("", "The type N1.N2.N3 is deprecated",
+ M1Path, 198, 200, CategorizedProblem.CAT_DEPRECATION, IMarker.SEVERITY_WARNING));
+ expectingSpecificProblemFor(M1Path,
+ new Problem("", "The method foo() from the type N1.N2.N3 is deprecated",
+ M1Path, 217, 222, CategorizedProblem.CAT_DEPRECATION, IMarker.SEVERITY_WARNING));
+ M1Path = env.addClass(rootPath, "p", "M1", M1Contents);
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(new IPath[] {M1Path});
+ expectingSpecificProblemFor(M1Path,
+ new Problem("", "The type N1.N2.N3 is deprecated",
+ M1Path, 198, 200, CategorizedProblem.CAT_DEPRECATION, IMarker.SEVERITY_WARNING));
+ expectingSpecificProblemFor(M1Path,
+ new Problem("", "The method foo() from the type N1.N2.N3 is deprecated",
+ M1Path, 217, 222, CategorizedProblem.CAT_DEPRECATION, IMarker.SEVERITY_WARNING));
+}
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/EfficiencyCompilerRequestor.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/EfficiencyCompilerRequestor.java
new file mode 100644
index 0000000000..1a7db581b9
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/EfficiencyCompilerRequestor.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import java.util.ArrayList;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.IDebugRequestor;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class EfficiencyCompilerRequestor implements IDebugRequestor {
+ private boolean isActive = false;
+
+ private ArrayList compiledClasses = new ArrayList<>();
+ private ArrayList compiledFiles = new ArrayList<>();
+ private ArrayList classes = new ArrayList<>();
+
+
+ public void acceptDebugResult(CompilationResult result){
+ this.compiledFiles.add(new String(result.fileName));
+ ClassFile[] classFiles = result.getClassFiles();
+ Util.sort(classFiles, new Util.Comparer() {
+ public int compare(Object a, Object b) {
+ String aName = new String(((ClassFile)a).fileName());
+ String bName = new String(((ClassFile)b).fileName());
+ return aName.compareTo(bName);
+ }
+ });
+ for (int i = 0; i < classFiles.length; i++) {
+ ClassFile c = classFiles[i];
+ this.classes.add(c);
+ String className = new String(c.fileName());
+ this.compiledClasses.add(className.replace('/', '.'));
+ }
+ }
+
+ String[] getCompiledClasses(){
+ return this.compiledClasses.toArray(new String[this.compiledClasses.size()]);
+ }
+
+ String[] getCompiledFiles(){
+ return this.compiledFiles.toArray(new String[this.compiledFiles.size()]);
+ }
+ public ClassFile[] getClassFiles() {
+ return this.classes.toArray(new ClassFile[this.classes.size()]);
+ }
+
+ public void clearResult(){
+ this.compiledClasses.clear();
+ this.compiledFiles.clear();
+ this.classes.clear();
+ }
+
+ public void reset() {
+ // do nothing by default
+ }
+
+ public void activate() {
+ this.isActive = true;
+ }
+
+ public void deactivate() {
+ this.isActive = false;
+ }
+
+ public boolean isActive() {
+ return this.isActive;
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/EfficiencyTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/EfficiencyTests.java
new file mode 100644
index 0000000000..02237c6eae
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/EfficiencyTests.java
@@ -0,0 +1,415 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import junit.framework.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.tests.util.Util;
+
+/**
+ * Basic efficiency tests of the image builder.
+ */
+public class EfficiencyTests extends BuilderTests {
+ public EfficiencyTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(EfficiencyTests.class);
+ }
+
+ public void testProjectAsClassFolder() throws JavaModelException {
+ IPath projectPath1 = env.addProject("Project1"); //$NON-NLS-1$
+ env.addExternalJars(projectPath1, Util.getJavaClassLibs());
+
+ IPath projectPath2 = env.addProject("Project2"); //$NON-NLS-1$
+ env.addExternalJars(projectPath2, Util.getJavaClassLibs());
+ env.addClassFolder(projectPath2, projectPath1, false);
+
+ env.addClass(projectPath2, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public abstract class X {}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(projectPath2, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Y {}\n" //$NON-NLS-1$
+ );
+
+ fullBuild();
+
+ env.addClass(projectPath2, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath2);
+
+ // if a full build happens instead of an incremental, then both types will be recompiled
+ expectingCompiledClasses(new String[]{"p1.X"}); //$NON-NLS-1$
+ }
+
+ public void testEfficiency() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Indicted", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public abstract class Indicted {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "Collaborator", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Collaborator extends Indicted{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+
+ env.addClass(root, "p1", "Indicted", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public abstract class Indicted {\n"+ //$NON-NLS-1$
+ " public abstract void foo();\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ expectingCompiledClasses(new String[]{"p2.Collaborator", "p1.Indicted"}); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingCompilingOrder(new String[] { "/Project/src/p1/Indicted.java", "/Project/src/p2/Collaborator.java" });
+ }
+
+ public void testMethodAddition() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Y extends X{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p3", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Z{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void bar(){} \n" + //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " }; \n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ expectingCompiledClasses(new String[]{"p1.X", "p2.Y"}); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingCompilingOrder(new String[] { "/Project/src/p1/X.java", "/Project/src/p2/Y.java" });
+ }
+
+ public void testLocalTypeAddition() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Y extends X{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p3", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Z{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " new Object(){ \n" + //$NON-NLS-1$
+ " }; \n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ expectingCompiledClasses(new String[]{"p1.X", "p1.X$1"}); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingCompilingOrder(new String[] { "/Project/src/p1/X.java" });
+ }
+
+ public void testLocalTypeAddition2() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " new X(){ \n" + //$NON-NLS-1$
+ " void bar(){} \n" + //$NON-NLS-1$
+ " }; \n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Y extends X{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p3", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Z{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " new Object(){ \n" + //$NON-NLS-1$
+ " }; \n" + //$NON-NLS-1$
+ " new X(){ \n" + //$NON-NLS-1$
+ " void bar(){} \n" + //$NON-NLS-1$
+ " }; \n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ expectingCompiledClasses(new String[]{"p1.X", "p1.X$1", "p1.X$2"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ expectingCompilingOrder(new String[] { "/Project/src/p1/X.java" });
+ }
+
+ public void testLocalTypeRemoval() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " new Object(){ \n" + //$NON-NLS-1$
+ " }; \n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Y extends X{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p3", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Z{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ expectingCompiledClasses(new String[]{"p1.X"}); //$NON-NLS-1$
+ expectingCompilingOrder(new String[] { "/Project/src/p1/X.java" });
+ }
+
+ public void testLocalTypeRemoval2() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " new Object(){ \n" + //$NON-NLS-1$
+ " }; \n" + //$NON-NLS-1$
+ " new X(){ \n" + //$NON-NLS-1$
+ " void bar(){} \n" + //$NON-NLS-1$
+ " }; \n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Y extends X{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p3", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Z{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " new X(){ \n" + //$NON-NLS-1$
+ " void bar(){} \n" + //$NON-NLS-1$
+ " }; \n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ expectingCompiledClasses(new String[]{"p1.X", "p1.X$1"}); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingCompilingOrder(new String[] { "/Project/src/p1/X.java" });
+ }
+ // http://dev.eclipse.org/bugs/show_bug.cgi?id=196200 - variation
+ public void testMissingType001() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo(p2.Y y) { \n" + //$NON-NLS-1$
+ " y.bar(null);" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ env.addClass(root, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Y {\n"+ //$NON-NLS-1$
+ " public void bar(Z z) {}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ fullBuild(projectPath);
+
+ env.addClass(root, "p2", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Z {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ expectingCompiledClasses(new String[]{"p1.X", "p2.Y","p2.Z"}); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingCompilingOrder(
+ new String[] { "/Project/src/p2/Z.java", "/Project/src/p2/Y.java", "/Project/src/p1/X.java" });
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ErrorsTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ErrorsTests.java
new file mode 100644
index 0000000000..6d698defc8
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ErrorsTests.java
@@ -0,0 +1,648 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Hashtable;
+
+import junit.framework.Test;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IRegion;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.core.util.IClassFileReader;
+import org.eclipse.jdt.core.util.IMethodInfo;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.core.builder.JavaBuilder;
+
+
+/**
+ * Basic errors tests of the image builder.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class ErrorsTests extends BuilderTests {
+ private static final IClasspathAttribute ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE = JavaCore.newClasspathAttribute(IClasspathAttribute.IGNORE_OPTIONAL_PROBLEMS, "true");
+
+ private static final Comparator COMPARATOR = new Comparator() {
+ public int compare(Object o1, Object o2) {
+ IResource resource1 = (IResource) o1;
+ IResource resource2 = (IResource) o2;
+ String path1 = resource1.getFullPath().toString();
+ String path2 = resource2.getFullPath().toString();
+ int length1 = path1.length();
+ int length2 = path2.length();
+
+ if (length1 != length2) {
+ return length1 - length2;
+ }
+ return path1.toString().compareTo(path2.toString());
+ }
+ };
+
+ public ErrorsTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(ErrorsTests.class);
+ }
+
+ public void testErrors() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Indicted", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public abstract class Indicted {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ IPath collaboratorPath = env.addClass(root, "p2", "Collaborator", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "import p1.*;\n"+ //$NON-NLS-1$
+ "public class Collaborator extends Indicted{\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p1", "Indicted", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public abstract class Indicted {\n"+ //$NON-NLS-1$
+ " public abstract void foo();\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ expectingOnlyProblemsFor(collaboratorPath);
+ expectingOnlySpecificProblemFor(collaboratorPath, new Problem("Collaborator", "The type Collaborator must implement the inherited abstract method Indicted.foo()", collaboratorPath, 38, 50, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /*
+ * Regression test for bug 2857 Renaming .java class with errors to .txt leaves errors in Task list (1GK06R3)
+ */
+ public void testRenameToNonJava() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath,""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath cuPath = env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X extends Y {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ fullBuild(projectPath);
+ expectingOnlyProblemsFor(cuPath);
+ expectingOnlySpecificProblemFor(cuPath, new Problem("X", "Y cannot be resolved to a type", cuPath, 35, 36, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+
+ env.renameCU(root.append("p1"), "X.java", "X.txt"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=158611
+// Checking the GENERATED_BY attribute
+public void test0100() throws JavaModelException {
+ IPath projectPath = env.addProject("Project");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.removePackageFragmentRoot(projectPath, "");
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ IPath classTest1 = env.addClass(root, "p1", "Test1",
+ "package p1;\n" +
+ "public class Test1 extends Test2 {}"
+ );
+ fullBuild();
+ Problem[] prob1 = env.getProblemsFor(classTest1);
+ expectingSpecificProblemFor(classTest1, new Problem("p1", "Test2 cannot be resolved to a type", classTest1, 39, 44, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR));
+ assertEquals(JavaBuilder.SOURCE_ID, prob1[0].getSourceId());
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=158611
+// Checking the GENERATED_BY attribute
+public void test0101() throws JavaModelException {
+ IPath projectPath = env.addProject("Project");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.removePackageFragmentRoot(projectPath, "");
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ IPath classTest1 = env.addClass(root, "p1", "Test1",
+ "package p1;\n" +
+ "public class Test1 extends {}"
+ );
+ fullBuild();
+ Problem[] prob1 = env.getProblemsFor(classTest1);
+ expectingSpecificProblemFor(classTest1, new Problem("p1", "Syntax error on token \"extends\", Type expected after this token", classTest1, 31, 38, CategorizedProblem.CAT_SYNTAX, IMarker.SEVERITY_ERROR));
+ assertEquals(JavaBuilder.SOURCE_ID, prob1[0].getSourceId());
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=158611
+// Checking the GENERATED_BY attribute
+public void test0102() throws JavaModelException {
+ IPath projectPath = env.addProject("Project");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.removePackageFragmentRoot(projectPath, "");
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ IPath classTest1 = env.addClass(root, "p1", "Test1",
+ "package p1;\n" +
+ "public class Test1 {\n" +
+ " private static int i;\n" +
+ " int j = i;\n" +
+ "}\n" +
+ "class Test2 {\n" +
+ " static int i = Test1.i;\n" +
+ "}\n"
+ );
+ fullBuild();
+ Problem[] prob1 = env.getProblemsFor(classTest1);
+ expectingSpecificProblemFor(classTest1, new Problem("p1", "The field Test1.i is not visible", classTest1, 109, 110, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR));
+ assertEquals(JavaBuilder.SOURCE_ID, prob1[0].getSourceId());
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=158611
+// Checking the GENERATED_BY attribute
+public void test0103() throws JavaModelException {
+ IPath projectPath = env.addProject("Project");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.removePackageFragmentRoot(projectPath, "");
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ IPath classTest1 = env.addClass(root, "p1", "Test1",
+ "package p1;\n" +
+ "public class Test1 {\n" +
+ " // TODO: marker only\n" +
+ "}\n"
+ );
+ fullBuild();
+ Problem[] prob1 = env.getProblemsFor(classTest1);
+ expectingSpecificProblemFor(classTest1, new Problem("p1", "TODO: marker only", classTest1, 38, 55, -1, IMarker.SEVERITY_ERROR));
+ assertEquals(JavaBuilder.SOURCE_ID, prob1[0].getSourceId());
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=158611
+// Checking the GENERATED_BY attribute
+public void test0104() throws JavaModelException {
+ IPath projectPath = env.addProject("Project");
+ env.removePackageFragmentRoot(projectPath, "");
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ IPath classTest1 = env.addClass(root, "p1", "Test1",
+ "package p1;\n" +
+ "public class Test1 {}"
+ );
+ fullBuild();
+ Problem[] prob1 = env.getProblemsFor(classTest1);
+ expectingSpecificProblemFor(classTest1,
+ new Problem("p1", "The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files", classTest1, 0, 1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR));
+ assertEquals(JavaBuilder.SOURCE_ID, prob1[0].getSourceId());
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=97998
+// Improving the error message in case of a read-only file in output
+// directory. Beware: this test only works under Linux - execution on other
+// platforms always succeeds, but the result is not significant.
+public void _test0105() throws JavaModelException, CoreException, IOException { // FIXME: re-enable!
+ if ("Linux".equals(System.getProperty("os.name"))) {
+ IPath projectPath = env.addProject("P");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ IPath root = env.getPackageFragmentRootPath(projectPath, "");
+ IPath outputFolderPath = env.getOutputLocation(projectPath);
+ File outputFolder = env.getWorkspaceRootPath().append(outputFolderPath).toFile();
+ env.addClass(root, "p1",
+ "X",
+ "package p1;\n" +
+ "public class X {\n" +
+ "}\n"
+ );
+ try {
+ fullBuild(projectPath);
+ expectingNoProblems();
+ outputFolder.setReadOnly();
+ // outputFolder.setReadable(false);
+ // PREMATURE no appropriate solution for Windows/NTFS/JDK 1.4
+ System.err.println("\n\n=== EXPECTED EXCEPTION =========================================================");
+ System.err.println("ErrorsTests#test0105 will emit an expected exception below");
+ cleanBuild();
+ System.err.println("=== END OF EXPECTED EXCEPTION ==================================================\n\n");
+ expectingOnlySpecificProblemFor(env.getWorkspaceRootPath(),
+ new Problem("",
+ "The project was not built due to \"Could not delete \'" +
+ env.getWorkspaceRootPath() + "/P/bin/.classpath\'.\". " +
+ "Fix the problem, then try refreshing this project and building " +
+ "it since it may be inconsistent", projectPath, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR));
+ } finally {
+ // waiting for JDK 6: outputFolder.setWritable(true); -- workaround:
+ Process process = null;
+ try {
+ process = Runtime.getRuntime().exec("chmod -R a+w " + outputFolder.getAbsolutePath());
+ process.waitFor();
+ } catch (InterruptedException e) {
+ // go ahead
+ } finally {
+ if (process != null) {
+ process.destroy();
+ }
+ }
+ }
+ try {
+ cleanBuild();
+ expectingNoProblems();
+ } catch (Throwable t) {
+ Process process = null;
+ try {
+ process = Runtime.getRuntime().exec("chmod -R a+w " + outputFolder.getAbsolutePath());
+ process.waitFor();
+ } catch (InterruptedException ie) {
+ // go ahead
+ } finally {
+ if (process != null) {
+ process.destroy();
+ }
+ }
+ fail(t.getMessage());
+ }
+ }
+}
+
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=224715
+public void test0106() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src", null, null); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath classTest1 = env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X implements I {\n" +
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addClass(root, "p1", "I", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public interface I {\n" +
+ " public void foo() {\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ expectingSpecificProblemFor(classTest1, new Problem("p1", "The type X must implement the inherited abstract method I.foo()", classTest1, 25, 26, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR));
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IRegion region = JavaCore.newRegion();
+ region.add(project);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/I.class\n" +
+ "/Project/bin/p1/X.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ assertEquals("Wrong type", IResource.FILE, resources[1].getType());
+ IFile classFile = (IFile) resources[1];
+ IClassFileReader classFileReader = null;
+ InputStream stream = null;
+ try {
+ stream = classFile.getContents();
+ classFileReader = ToolFactory.createDefaultClassFileReader(stream, IClassFileReader.ALL);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch(IOException e) {
+ // ignore
+ }
+ }
+ }
+ assertNotNull("No class file reader", classFileReader);
+ IMethodInfo[] methodInfos = classFileReader.getMethodInfos();
+ IMethodInfo found = null;
+ loop: for (int i = 0, max = methodInfos.length; i < max; i++) {
+ IMethodInfo methodInfo = methodInfos[i];
+ if (CharOperation.equals(methodInfo.getName(), "foo".toCharArray())) {
+ found = methodInfo;
+ break loop;
+ }
+ }
+ assertNotNull("No method found", found);
+ assertTrue("Not a synthetic method", found.isSynthetic());
+ env.removeProject(projectPath);
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=225563
+public void test0107() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src", null, null); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath classTest1 = env.addClass(root, "", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class C implements None {\n" +
+ " public String toString(Arg a) {\n" +
+ " return null;\n" +
+ " }\n" +
+ " public String toString(Arg[] a) {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ expectingOnlySpecificProblemsFor(classTest1, new Problem[] {
+ new Problem("", "None cannot be resolved to a type", classTest1, 26, 30, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR),
+ new Problem("", "Arg cannot be resolved to a type", classTest1, 64, 67, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR),
+ new Problem("", "Arg cannot be resolved to a type", classTest1, 143, 146, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)
+ });
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IRegion region = JavaCore.newRegion();
+ region.add(project);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 1, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/C.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ assertEquals("Wrong type", IResource.FILE, resources[0].getType());
+ IFile classFile = (IFile) resources[0];
+ InputStream stream = null;
+ try {
+ stream = classFile.getContents();
+ ClassFileReader.read(stream, "C.java");
+ } catch (Exception e) {
+ e.printStackTrace();
+ assertTrue("Should not happen", false);
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch(IOException e) {
+ // ignore
+ }
+ }
+ }
+}
+private String getResourceOuput(IResource[] resources) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter writer = new PrintWriter(stringWriter);
+ for (int i = 0, max = resources.length; i < max; i++) {
+ writer.println(resources[i].getFullPath().toString());
+ }
+ writer.flush();
+ writer.close();
+ return Util.convertToIndependantLineDelimiter(String.valueOf(stringWriter));
+}
+
+// ignore optional errors
+public void test0108() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR);
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("P");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ env.setOutputFolder(projectPath, "bin");
+ IPath root = new Path("/P/src");
+ env.addEntry(projectPath, JavaCore.newSourceEntry(root, null, null,
+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }));
+
+ env.addClass(root, "p", "X",
+ "package p;\n" +
+ "public class X {\n" +
+ " public void foo() {\n" +
+ " int i;\n" +
+ " }\n" +
+ "}");
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ JavaCore.setOptions(options);
+}
+
+// two different source folders ignore only from one
+public void test0109() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR);
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("P");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ env.setOutputFolder(projectPath, "bin");
+ IPath src = new Path("/P/src");
+ IPath src2 = new Path("/P/src2");
+ env.addEntry(projectPath, JavaCore.newSourceEntry(src, null, null,
+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }));
+ env.addEntry(projectPath, JavaCore.newSourceEntry(src2));
+
+ env.addClass(src, "p", "X",
+ "package p;\n" +
+ "public class X {\n" +
+ " public void foo() {\n" +
+ " int i;\n" +
+ " }\n" +
+ "}");
+
+ IPath classY = env.addClass(src2, "q", "Y",
+ "package q;\n" +
+ "public class Y {\n" +
+ " public void foo() {\n" +
+ " int i;\n" +
+ " }\n" +
+ "}");
+
+ fullBuild(projectPath);
+ expectingNoProblemsFor(src);
+ expectingOnlySpecificProblemFor(classY, new Problem("q", "The value of the local variable i is not used", classY, 55, 56, CategorizedProblem.CAT_UNNECESSARY_CODE, IMarker.SEVERITY_ERROR));
+
+ JavaCore.setOptions(options);
+}
+
+// two different source folders ignore from both
+public void test0110() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR);
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("P");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ env.setOutputFolder(projectPath, "bin");
+ IPath src = new Path("/P/src");
+ IPath src2 = new Path("/P/src2");
+ env.addEntry(projectPath, JavaCore.newSourceEntry(src, null, null,
+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }));
+ env.addEntry(projectPath, JavaCore.newSourceEntry(src2, null, null,
+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }));
+
+ env.addClass(src, "p", "X",
+ "package p;\n" +
+ "public class X {\n" +
+ " public void foo() {\n" +
+ " int i;\n" +
+ " }\n" +
+ "}");
+
+ env.addClass(src2, "q", "Y",
+ "package q;\n" +
+ "public class Y {\n" +
+ " public void foo() {\n" +
+ " int i;\n" +
+ " }\n" +
+ "}");
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ JavaCore.setOptions(options);
+}
+
+//non-optional errors cannot be ignored
+public void test0111() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR);
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("P");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ env.setOutputFolder(projectPath, "bin");
+ IPath root = new Path("/P/src");
+ env.addEntry(projectPath, JavaCore.newSourceEntry(root, null, null,
+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }));
+
+ IPath classX = env.addClass(root, "p", "X",
+ "package p;\n" +
+ "public class X {\n" +
+ " public void foo() {\n" +
+ " int i;\n" +
+ " }\n" +
+ " public void bar() {\n" +
+ " a++;\n" +
+ " }\n" +
+ "}");
+
+ fullBuild(projectPath);
+ expectingOnlySpecificProblemFor(classX, new Problem("p", "a cannot be resolved to a variable", classX, 84, 85, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR));
+
+ JavaCore.setOptions(options);
+}
+
+//task tags cannot be ignored
+public void test0112() throws JavaModelException {
+ Hashtable options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR);
+ newOptions.put(JavaCore.COMPILER_TASK_TAGS, "TODO");
+ newOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL");
+
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("P");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ env.setOutputFolder(projectPath, "bin");
+ IPath root = new Path("/P/src");
+ env.addEntry(projectPath, JavaCore.newSourceEntry(root, null, null,
+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }));
+
+ IPath classX = env.addClass(root, "p", "X",
+ "package p;\n" +
+ "public class X {\n" +
+ " public void foo() {\n" +
+ " int i;\n" +
+ " }\n" +
+ " public void bar() {\n" +
+ " // TODO nothing\n" +
+ " }\n" +
+ "}");
+
+ fullBuild(projectPath);
+ expectingOnlySpecificProblemFor(classX, new Problem("p", "TODO nothing", classX, 87, 99, -1, IMarker.SEVERITY_ERROR));
+
+ JavaCore.setOptions(options);
+}
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ExecutionTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ExecutionTests.java
new file mode 100644
index 0000000000..0cc33c5ca5
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ExecutionTests.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import junit.framework.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.tests.util.Util;
+
+/**
+ * Basic execution tests of the image builder.
+ */
+public class ExecutionTests extends BuilderTests {
+ public ExecutionTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(ExecutionTests.class);
+ }
+
+ public void testSuccess() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.print(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ executeClass(projectPath, "p1.Hello", "Hello world", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ public void testFailure() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath helloPath = env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\")\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ // public static void main(String args[]) {
+ // System.out.println("Hello world") <-- missing ";"
+ // }
+
+ incrementalBuild(projectPath);
+ expectingOnlyProblemsFor(helloPath);
+ executeClass(projectPath, "p1.Hello", "", //$NON-NLS-1$ //$NON-NLS-2$
+ "java.lang.Error: Unresolved compilation problem: \n" + //$NON-NLS-1$
+ " Syntax error, insert \";\" to complete BlockStatements\n" //$NON-NLS-1$
+ );
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/FriendDependencyTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/FriendDependencyTests.java
new file mode 100644
index 0000000000..0bf8794963
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/FriendDependencyTests.java
@@ -0,0 +1,323 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import junit.framework.Test;
+
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.builder.ReferenceCollection;
+import org.eclipse.jdt.internal.core.builder.State;
+import org.eclipse.jdt.internal.core.builder.StringSet;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class FriendDependencyTests extends BuilderTests {
+
+ public FriendDependencyTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(FriendDependencyTests.class);
+ }
+// this is a compilation only test to verify that this method still exists since API Tooling is using it
+public void testIncludes() {
+ try {
+ State state = (State) JavaModelManager.getJavaModelManager().getLastBuiltState(null, null);
+ SimpleLookupTable references = state.getReferences();
+ ReferenceCollection r = (ReferenceCollection) references.valueTable[0];
+ char[][][] qualifiedNames = null;
+ char[][] simpleNames = null;
+ char[][] rootNames = null;
+ r.includes(qualifiedNames, simpleNames, rootNames);
+ } catch (NullPointerException e) {
+ // expected
+ }
+}
+
+// this is a compilation only test to verify that this method still exists since API Tooling is using it
+public void testInternSimpleNames() {
+ ReferenceCollection.internSimpleNames(new StringSet(1), true);
+
+ try {
+ String className = "org.eclipse.jdt.internal.core.builder.ReferenceCollection";
+ Class clazz = Class.forName(className);
+ //org.eclipse.jdt.internal.core.JavaModelManager.getLastBuiltState(IProject, IProgressMonitor)
+ Class[] arguments = new Class[2];
+ String argumentClassName = "org.eclipse.jdt.internal.core.builder.StringSet";
+ arguments[0] = Class.forName(argumentClassName);
+ arguments[1] = Boolean.TYPE;
+ clazz.getDeclaredMethod("internSimpleNames", arguments);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+
+//this is a compilation only test to verify that this method still exists since API Tooling is using it
+public void testInternQualifiedNames() {
+ ReferenceCollection.internQualifiedNames(new StringSet(1));
+
+ try {
+ String className = "org.eclipse.jdt.internal.core.builder.ReferenceCollection";
+ Class clazz = Class.forName(className);
+ //org.eclipse.jdt.internal.core.JavaModelManager.getLastBuiltState(IProject, IProgressMonitor)
+ Class[] arguments = new Class[1];
+ String argumentClassName = "org.eclipse.jdt.internal.core.builder.StringSet";
+ arguments[0] = Class.forName(argumentClassName);
+ clazz.getDeclaredMethod("internQualifiedNames", arguments);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+//this is a compilation only test to verify that this method still exists since API Tooling is using it
+public void testGetReferences() {
+ try {
+ State state = (State) JavaModelManager.getJavaModelManager().getLastBuiltState(null, null);
+ state.getReferences();
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ String className = "org.eclipse.jdt.internal.core.builder.State";
+ Class clazz = Class.forName(className);
+ clazz.getDeclaredMethod("getReferences", new Class[0]);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+//this is a compilation only test to verify that this method still exists since API Tooling is using it
+public void testStringSetAdd() {
+ StringSet s = new StringSet(3);
+ s.add("");
+
+ try {
+ String className = "org.eclipse.jdt.internal.core.builder.StringSet";
+ Class clazz = Class.forName(className);
+ Class[] arguments = new Class[1];
+ String argumentClassName = "java.lang.String";
+ arguments[0] = Class.forName(argumentClassName);
+ clazz.getDeclaredMethod("add", arguments);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+//this is a compilation only test to verify that this method still exists since API Tooling is using it
+public void testStringSetclear() {
+ StringSet s = new StringSet(3);
+ s.clear();
+
+ try {
+ String className = "org.eclipse.jdt.internal.core.builder.StringSet";
+ Class clazz = Class.forName(className);
+ clazz.getDeclaredMethod("clear", new Class[0]);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+//this is a compilation only test to verify that this method still exists since API Tooling is using it
+public void testStringSetNew() {
+ new StringSet(3);
+
+ try {
+ String className = "org.eclipse.jdt.internal.core.builder.StringSet";
+ Class clazz = Class.forName(className);
+ Class[] arguments = new Class[1];
+ arguments[0] = Integer.TYPE;
+ clazz.getDeclaredConstructor(arguments);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+//this is a compilation only test to verify that this field still exists since API Tooling is using it
+public void testStringSetElementSize() {
+ StringSet s = new StringSet(3);
+ assertEquals("Not expected", 0, s.elementSize);
+
+ try {
+ String className = "org.eclipse.jdt.internal.core.builder.StringSet";
+ Class clazz = Class.forName(className);
+ clazz.getDeclaredField("elementSize");
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+//this is a compilation only test to verify that this field still exists since API Tooling is using it
+public void testSimpleLookupTableKeyTable() {
+ SimpleLookupTable t = new SimpleLookupTable(3);
+ assertNotNull("Null", t.keyTable);
+
+ try {
+ String className = "org.eclipse.jdt.internal.compiler.util.SimpleLookupTable";
+ Class clazz = Class.forName(className);
+ clazz.getDeclaredField("keyTable");
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+//this is a compilation only test to verify that this field still exists since API Tooling is using it
+public void testSimpleLookupTableValueTable() {
+ SimpleLookupTable t = new SimpleLookupTable(3);
+ assertNotNull("Null", t.valueTable);
+
+ try {
+ String className = "org.eclipse.jdt.internal.compiler.util.SimpleLookupTable";
+ Class clazz = Class.forName(className);
+ clazz.getDeclaredField("valueTable");
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+//this is a compilation only test to verify that this method still exists since API Tooling is using it
+public void testJavaModelManagerGetJavaModelManager() {
+ JavaModelManager.getJavaModelManager();
+ try {
+ String className = "org.eclipse.jdt.internal.core.JavaModelManager";
+ Class clazz = Class.forName(className);
+ clazz.getDeclaredMethod("getJavaModelManager", new Class[0]);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+//this is a compilation only test to verify that this method still exists since API Tooling is using it
+public void testJavaModelManagerGetLastBuiltState() {
+ try {
+ JavaModelManager.getJavaModelManager().getLastBuiltState(null, null);
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ String className = "org.eclipse.jdt.internal.core.JavaModelManager";
+ Class clazz = Class.forName(className);
+ //org.eclipse.jdt.internal.core.JavaModelManager.getLastBuiltState(IProject, IProgressMonitor)
+ Class[] arguments = new Class[2];
+ String argumentClassName = "org.eclipse.core.resources.IProject";
+ String argumentClassName2 = "org.eclipse.core.runtime.IProgressMonitor";
+ arguments[0] = Class.forName(argumentClassName);
+ arguments[1] = Class.forName(argumentClassName2);
+ clazz.getDeclaredMethod("getLastBuiltState", arguments);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ assertTrue("Should be there", false);
+ }
+}
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/GetResourcesTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/GetResourcesTests.java
new file mode 100644
index 0000000000..9ddf18f728
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/GetResourcesTests.java
@@ -0,0 +1,1018 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import junit.framework.Test;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IRegion;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.tests.util.Util;
+
+/**
+ * Basic tests of {@link JavaCore#getGeneratedResources(IRegion, boolean)}.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class GetResourcesTests extends BuilderTests {
+
+ private static final Comparator COMPARATOR = new Comparator() {
+ public int compare(Object o1, Object o2) {
+ IResource resource1 = (IResource) o1;
+ IResource resource2 = (IResource) o2;
+ String path1 = resource1.getFullPath().toString();
+ String path2 = resource2.getFullPath().toString();
+ int length1 = path1.length();
+ int length2 = path2.length();
+
+ if (length1 != length2) {
+ return length1 - length2;
+ }
+ return path1.toString().compareTo(path2.toString());
+ }
+ };
+
+ public GetResourcesTests(String name) {
+ super(name);
+ }
+
+ static {
+// TESTS_NUMBERS = new int[] { 15 };
+ }
+
+ public static Test suite() {
+ return buildTestSuite(GetResourcesTests.class);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test001() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ ICompilationUnit compilationUnit = packageFragment.getCompilationUnit("Hello.java");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(compilationUnit);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 1, resources.length);//$NON-NLS-1$
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput = "/Project/bin/p1/Hello.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test002() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n"+ //$NON-NLS-1$
+ " Object foo() {\n" + //$NON-NLS-1$
+ " return new Object() {};\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ ICompilationUnit compilationUnit = packageFragment.getCompilationUnit("Hello.java");//$NON-NLS-1$
+
+ IRegion region = JavaCore.newRegion();
+ region.add(compilationUnit);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$1.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test003() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n"+ //$NON-NLS-1$
+ " Object foo() {\n" +
+ " if(false) {\n" + //$NON-NLS-1$
+ " return new Object() {};\n" +
+ " }\n" +
+ " return null;\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ ICompilationUnit compilationUnit = packageFragment.getCompilationUnit("Hello.java");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(compilationUnit);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 1, resources.length);//$NON-NLS-1$
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput = "/Project/bin/p1/Hello.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test004() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n"+ //$NON-NLS-1$
+ " Object foo() {\n" +
+ " return new Object() {};\n" +
+ " }\n" + //$NON-NLS-1$
+ " Object foo2() {\n" +
+ " return new Object() {};\n" +
+ " }\n" + //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ ICompilationUnit compilationUnit = packageFragment.getCompilationUnit("Hello.java");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(compilationUnit);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 3, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$1.class\n" +
+ "/Project/bin/p1/Hello$2.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test005() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "a", "Anon", //$NON-NLS-1$ //$NON-NLS-2$
+ "package a;\n" +
+ "\n" +
+ "public class Anon {\n" +
+ "\n" +
+ " Anon() {\n" +
+ " Object o1 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"1\"; // a/Anon$3 in 1.5, a/Anon$11 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o2 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"2\"; // a/Anon$4 in 1.5, a/Anon$12 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " void hello() {\n" +
+ " Object o3 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"3\"; // a/Anon$5 in 1.5, a/Anon$13 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o4 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"4\"; // a/Anon$6 in 1.5, a/Anon$14 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " static void hello2() {\n" +
+ " Object o5 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"5\"; // a/Anon$7 in 1.5, a/Anon$15 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o6 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"6\"; // a/Anon$8 in 1.5, a/Anon$16 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " static {\n" +
+ " Object o7 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"7\"; // a/Anon$1 in 1.5, a/Anon$1 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ "\n" +
+ " Object o8 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"8\"; // a/Anon$2 in 1.5, a/Anon$2 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " static class Anon2 {\n" +
+ " // it\'s an object init block which has different prio as constructor!\n" +
+ " {\n" +
+ " Object o1 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"1\"; // a/Anon$Anon2$1 in 1.5, a/Anon$3 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o2 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"2\"; // a/Anon$Anon2$2 in 1.5, a/Anon$4 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " void hello() {\n" +
+ " Object o3 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"3\"; // a/Anon$Anon2$5 in 1.5, a/Anon$7 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o4 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"4\"; // a/Anon$Anon2$6 in 1.5, a/Anon$8 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " static void hello2() {\n" +
+ " Object o5 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"5\"; // a/Anon$Anon2$7 in 1.5, a/Anon$9 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o6 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"6\"; // a/Anon$Anon2$8 in 1.5, a/Anon$10 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " static {\n" +
+ " Object o7 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"7\"; // a/Anon$Anon2$3 in 1.5, a/Anon$5 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ "\n" +
+ " Object o8 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"8\"; // a/Anon$Anon2$4 in 1.5, a/Anon$6 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("a");//$NON-NLS-1$
+ ICompilationUnit compilationUnit = packageFragment.getCompilationUnit("Anon.java");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(compilationUnit);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 18, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/a/Anon.class\n" +
+ "/Project/bin/a/Anon$1.class\n" +
+ "/Project/bin/a/Anon$2.class\n" +
+ "/Project/bin/a/Anon$3.class\n" +
+ "/Project/bin/a/Anon$4.class\n" +
+ "/Project/bin/a/Anon$5.class\n" +
+ "/Project/bin/a/Anon$6.class\n" +
+ "/Project/bin/a/Anon$7.class\n" +
+ "/Project/bin/a/Anon$8.class\n" +
+ "/Project/bin/a/Anon$9.class\n" +
+ "/Project/bin/a/Anon$10.class\n" +
+ "/Project/bin/a/Anon$11.class\n" +
+ "/Project/bin/a/Anon$12.class\n" +
+ "/Project/bin/a/Anon$13.class\n" +
+ "/Project/bin/a/Anon$14.class\n" +
+ "/Project/bin/a/Anon$15.class\n" +
+ "/Project/bin/a/Anon$16.class\n" +
+ "/Project/bin/a/Anon$Anon2.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test006() throws JavaModelException {
+ IPath projectPath = null;
+ try {
+ projectPath = env.addProject("Project", "1.5"); //$NON-NLS-1$
+ } catch (RuntimeException e) {
+ // no 1.5 VM or above is available
+ return;
+ }
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "a", "Anon", //$NON-NLS-1$ //$NON-NLS-2$
+ "package a;\n" +
+ "\n" +
+ "public class Anon {\n" +
+ "\n" +
+ " Anon() {\n" +
+ " Object o1 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"1\"; // a/Anon$3 in 1.5, a/Anon$11 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o2 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"2\"; // a/Anon$4 in 1.5, a/Anon$12 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " void hello() {\n" +
+ " Object o3 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"3\"; // a/Anon$5 in 1.5, a/Anon$13 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o4 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"4\"; // a/Anon$6 in 1.5, a/Anon$14 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " static void hello2() {\n" +
+ " Object o5 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"5\"; // a/Anon$7 in 1.5, a/Anon$15 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o6 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"6\"; // a/Anon$8 in 1.5, a/Anon$16 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " static {\n" +
+ " Object o7 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"7\"; // a/Anon$1 in 1.5, a/Anon$1 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ "\n" +
+ " Object o8 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"8\"; // a/Anon$2 in 1.5, a/Anon$2 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " static class Anon2 {\n" +
+ " // it\'s an object init block which has different prio as constructor!\n" +
+ " {\n" +
+ " Object o1 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"1\"; // a/Anon$Anon2$1 in 1.5, a/Anon$3 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o2 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"2\"; // a/Anon$Anon2$2 in 1.5, a/Anon$4 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " void hello() {\n" +
+ " Object o3 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"3\"; // a/Anon$Anon2$5 in 1.5, a/Anon$7 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o4 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"4\"; // a/Anon$Anon2$6 in 1.5, a/Anon$8 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " static void hello2() {\n" +
+ " Object o5 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"5\"; // a/Anon$Anon2$7 in 1.5, a/Anon$9 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " Object o6 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"6\"; // a/Anon$Anon2$8 in 1.5, a/Anon$10 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " static {\n" +
+ " Object o7 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"7\"; // a/Anon$Anon2$3 in 1.5, a/Anon$5 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ "\n" +
+ " Object o8 = new Object() {\n" +
+ " public String toString() {\n" +
+ " return \"8\"; // a/Anon$Anon2$4 in 1.5, a/Anon$6 in 1.4\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ " }\n" +
+ "}");
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("a");//$NON-NLS-1$
+ ICompilationUnit compilationUnit = packageFragment.getCompilationUnit("Anon.java");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(compilationUnit);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 18, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/a/Anon.class\n" +
+ "/Project/bin/a/Anon$1.class\n" +
+ "/Project/bin/a/Anon$2.class\n" +
+ "/Project/bin/a/Anon$3.class\n" +
+ "/Project/bin/a/Anon$4.class\n" +
+ "/Project/bin/a/Anon$5.class\n" +
+ "/Project/bin/a/Anon$6.class\n" +
+ "/Project/bin/a/Anon$7.class\n" +
+ "/Project/bin/a/Anon$8.class\n" +
+ "/Project/bin/a/Anon$Anon2.class\n" +
+ "/Project/bin/a/Anon$Anon2$1.class\n" +
+ "/Project/bin/a/Anon$Anon2$2.class\n" +
+ "/Project/bin/a/Anon$Anon2$3.class\n" +
+ "/Project/bin/a/Anon$Anon2$4.class\n" +
+ "/Project/bin/a/Anon$Anon2$5.class\n" +
+ "/Project/bin/a/Anon$Anon2$6.class\n" +
+ "/Project/bin/a/Anon$Anon2$7.class\n" +
+ "/Project/bin/a/Anon$Anon2$8.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+ env.removeProject(projectPath);
+ }
+
+ private String getResourceOuput(IResource[] resources) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter writer = new PrintWriter(stringWriter);
+ for (int i = 0, max = resources.length; i < max; i++) {
+ writer.println(resources[i].getFullPath().toString());
+ }
+ writer.flush();
+ writer.close();
+ return Util.convertToIndependantLineDelimiter(String.valueOf(stringWriter));
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test007() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" + //$NON-NLS-1$
+ "class Foo {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ ICompilationUnit compilationUnit = packageFragment.getCompilationUnit("Hello.java");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(compilationUnit);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test008() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n" +
+ " public class Z {}\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(packageFragment);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test009() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(projectPath, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getUnderlyingResource());
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ ICompilationUnit compilationUnit = packageFragment.getCompilationUnit("Hello.java");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(compilationUnit);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 1, resources.length);//$NON-NLS-1$
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/Hello.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test010() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n" +
+ " public class Z {}\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ env.addFile(root, "p1/Test.txt", "This is a non-java resource");
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(packageFragment);
+ IResource[] resources = JavaCore.getGeneratedResources(region, false);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 3, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ actualOutput = getResourceOuput(resources);
+ expectedOutput =
+ "/Project/bin/p1/Test.txt\n" +
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test011() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n" +
+ " public class Z {}\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(packageFragment);
+ IResource[] resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.addFile(root, "p1/Test.txt", "This is a non-java resource");
+ incrementalBuild(projectPath);
+
+ resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 3, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ actualOutput = getResourceOuput(resources);
+ expectedOutput =
+ "/Project/bin/p1/Test.txt\n" +
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test012() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n" +
+ " public class Z {}\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(packageFragment);
+ IResource[] resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.addFile(root, "p1/Test.txt", "This is a non-java resource");
+
+ resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ actualOutput = getResourceOuput(resources);
+ expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test013() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src", new Path[] {new Path("**/*.txt")}, null); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n" +
+ " public class Z {}\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(packageFragment);
+ IResource[] resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.addFile(root, "p1/Test.txt", "This is a non-java resource");
+ incrementalBuild(projectPath);
+
+ resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ actualOutput = getResourceOuput(resources);
+ expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test014() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src", new Path[] {new Path("**/*.txt")}, null); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n" +
+ " public class Z {}\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IPackageFragmentRoot root2 = project.getPackageFragmentRoot(project.getProject().getWorkspace().getRoot().findMember(root.makeAbsolute()));
+ IPackageFragment packageFragment = root2.getPackageFragment("p1");//$NON-NLS-1$
+ IRegion region = JavaCore.newRegion();
+ region.add(packageFragment);
+ IResource[] resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.addFile(root, "p1/Test.txt", "This is an excluded non-java resource");
+ env.addFile(root, "p1/Test.log", "This is an included non-java resource");
+ incrementalBuild(projectPath);
+
+ resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 3, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ actualOutput = getResourceOuput(resources);
+ expectedOutput =
+ "/Project/bin/p1/Test.log\n" +
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test015() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src", new Path[] {new Path("**/*.txt")}, null); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p1", "Hello", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Hello {\n" +
+ " public class Z {}\n"+ //$NON-NLS-1$
+ " public static void main(String args[]) {\n"+ //$NON-NLS-1$
+ " System.out.println(\"Hello world\");\n"+ //$NON-NLS-1$
+ " }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(projectPath);
+
+ IJavaProject project = env.getJavaProject(projectPath);
+ IRegion region = JavaCore.newRegion();
+ region.add(project);
+ IResource[] resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 2, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ String actualOutput = getResourceOuput(resources);
+ String expectedOutput =
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.addFile(root, "p1/Test.txt", "This is an excluded non-java resource");
+ env.addFile(root, "p1/Test.log", "This is an included non-java resource");
+ incrementalBuild(projectPath);
+
+ resources = JavaCore.getGeneratedResources(region, true);
+ assertEquals("Wrong size", 3, resources.length);//$NON-NLS-1$
+ Arrays.sort(resources, COMPARATOR);
+ actualOutput = getResourceOuput(resources);
+ expectedOutput =
+ "/Project/bin/p1/Test.log\n" +
+ "/Project/bin/p1/Hello.class\n" +
+ "/Project/bin/p1/Hello$Z.class\n";
+ assertEquals("Wrong names", Util.convertToIndependantLineDelimiter(expectedOutput), actualOutput);
+
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=6584
+ public void test016() throws JavaModelException {
+ try {
+ JavaCore.getGeneratedResources(null, true);
+ assertTrue("Region cannot be null", false);
+ } catch(IllegalArgumentException e) {
+ // ignore: expected exception
+ }
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java
new file mode 100644
index 0000000000..67f061434c
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java
@@ -0,0 +1,1288 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import java.util.Hashtable;
+
+import junit.framework.Test;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.tests.util.Util;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class IncrementalTests extends BuilderTests {
+
+ public IncrementalTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(IncrementalTests.class);
+ }
+
+ /*
+ * Ensures that the source range for a duplicate secondary type error is correct
+ * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=77283)
+ */
+ public void testAddDuplicateSecondaryType() throws JavaModelException {
+ IPath projectPath = env.addProject("Project");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ env.addClass(root, "p", "C",
+ "package p; \n"+
+ "public class C {} \n"+
+ "class CC {}");
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ IPath pathToD = env.addClass(root, "p", "D",
+ "package p; \n"+
+ "public class D {} \n"+
+ "class CC {}");
+
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ pathToD,
+ "Problem : The type CC is already defined [ resource : range : <37,39> category : <-1> severity : <2>]"
+ );
+ expectingSpecificProblemsFor(pathToD, new Problem[] {new Problem("", "The type CC is already defined", pathToD, 37, 39, -1, IMarker.SEVERITY_ERROR)});
+ env.removeProject(projectPath);
+ }
+
+ public void testDefaultPackage() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, ""); //$NON-NLS-1$
+
+ env.addClass(projectPath, "", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class A {}"); //$NON-NLS-1$
+
+ env.addClass(projectPath, "", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class B {}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(projectPath, "", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class B {A a;}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ public void testDefaultPackage2() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(projectPath, "", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class A {}"); //$NON-NLS-1$
+
+ env.addClass(projectPath, "", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class B {}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(projectPath, "", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class B {A a;}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ public void testNewJCL() {
+ //----------------------------
+ // Step 1
+ //----------------------------
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+
+ IPath root = env.getPackageFragmentRootPath(projectPath, ""); //$NON-NLS-1$
+ fullBuild();
+ expectingNoProblems();
+
+ //----------------------------
+ // Step 2
+ //----------------------------
+ env.addClass(root, "java.lang", "Object", //$NON-NLS-1$ //$NON-NLS-2$
+ "package java.lang;\n" + //$NON-NLS-1$
+ "public class Object {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+
+ incrementalBuild();
+ expectingNoProblems();
+
+ //----------------------------
+ // Step 3
+ //----------------------------
+ env.addClass(root, "java.lang", "Throwable", //$NON-NLS-1$ //$NON-NLS-2$
+ "package java.lang;\n" + //$NON-NLS-1$
+ "public class Throwable {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+
+ incrementalBuild();
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ /*
+ * http://bugs.eclipse.org/bugs/show_bug.cgi?id=17329
+ */
+ public void testRenameMainType() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ /* A.java */
+ IPath pathToA = env.addClass(root, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class A {}"); //$NON-NLS-1$
+
+ /* B.java */
+ IPath pathToB = env.addClass(root, "p", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class B extends A {}"); //$NON-NLS-1$
+
+ /* C.java */
+ IPath pathToC = env.addClass(root, "p", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class C extends B {}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ /* Touch both A and C, removing A main type */
+ pathToA = env.addClass(root, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class _A {}"); //$NON-NLS-1$
+
+ pathToC = env.addClass(root, "p", "C", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class C extends B { }"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ new IPath[]{ pathToA, pathToB, pathToC },
+ "Problem : A cannot be resolved to a type [ resource : range : <35,36> category : <40> severity : <2>]\n" +
+ "Problem : The hierarchy of the type C is inconsistent [ resource : range : <25,26> category : <40> severity : <2>]\n" +
+ "Problem : The public type _A must be defined in its own file [ resource : range : <25,27> category : <40> severity : <2>]"
+ );
+ expectingSpecificProblemFor(pathToA, new Problem("_A", "The public type _A must be defined in its own file", pathToA, 25, 27, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(pathToB, new Problem("B", "A cannot be resolved to a type", pathToB, 35, 36, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(pathToC, new Problem("C", "The hierarchy of the type C is inconsistent", pathToC, 25, 26, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ /* Touch both A and C, removing A main type */
+ pathToA = env.addClass(root, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class A {}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ /*
+ * http://bugs.eclipse.org/bugs/show_bug.cgi?id=17807
+ * case 1
+ */
+ public void testRemoveSecondaryType() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA {} \n"+ //$NON-NLS-1$
+ "class AZ {}"); //$NON-NLS-1$
+
+ IPath pathToAB = env.addClass(root, "p", "AB", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AB extends AZ {}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "BB", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class BB { \n"+ //$NON-NLS-1$
+ " void foo(){ \n" + //$NON-NLS-1$
+ " System.out.println(new AB()); \n" + //$NON-NLS-1$
+ " System.out.println(new ZA()); \n" + //$NON-NLS-1$
+ " } \n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "ZZ", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class ZZ {} \n"+ //$NON-NLS-1$
+ "class ZA {}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ /* Remove AZ and touch BB */
+ env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA {}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "BB", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class BB { \n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " System.out.println(new AB()); \n" + //$NON-NLS-1$
+ " System.out.println(new ZA()); \n" + //$NON-NLS-1$
+ " } \n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ pathToAB,
+ "Problem : AZ cannot be resolved to a type [ resource : range : <36,38> category : <40> severity : <2>]"
+ );
+ expectingSpecificProblemFor(pathToAB, new Problem("AB", "AZ cannot be resolved to a type", pathToAB, 36, 38, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA {} \n"+ //$NON-NLS-1$
+ "class AZ {}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ /*
+ * http://bugs.eclipse.org/bugs/show_bug.cgi?id=17807
+ * case 2
+ */
+ public void testRemoveSecondaryType2() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA {} \n"+ //$NON-NLS-1$
+ "class AZ {}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "AB", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AB extends AZ {}"); //$NON-NLS-1$
+
+ IPath pathToBB = env.addClass(root, "p", "BB", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class BB { \n"+ //$NON-NLS-1$
+ " void foo(){ \n" + //$NON-NLS-1$
+ " System.out.println(new AB()); \n" + //$NON-NLS-1$
+ " System.out.println(new ZA()); \n" + //$NON-NLS-1$
+ " } \n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "ZZ", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class ZZ {} \n"+ //$NON-NLS-1$
+ "class ZA {}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ /* Remove ZA and touch BB */
+ env.addClass(root, "p", "ZZ", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class ZZ {}"); //$NON-NLS-1$
+
+ pathToBB = env.addClass(root, "p", "BB", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class BB { \n"+ //$NON-NLS-1$
+ " void foo() { \n" + //$NON-NLS-1$
+ " System.out.println(new AB()); \n" + //$NON-NLS-1$
+ " System.out.println(new ZA()); \n" + //$NON-NLS-1$
+ " } \n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ pathToBB,
+ "Problem : ZA cannot be resolved to a type [ resource : range : <104,106> category : <40> severity : <2>]"
+ );
+ expectingSpecificProblemFor(pathToBB, new Problem("BB.foo()", "ZA cannot be resolved to a type", pathToBB, 104, 106, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p", "ZZ", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class ZZ {} \n"+ //$NON-NLS-1$
+ "class ZA {}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ public void testMoveSecondaryType() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA {} \n"+ //$NON-NLS-1$
+ "class AZ {}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "AB", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AB extends AZ {}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "ZZ", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class ZZ {}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ /* Move AZ from AA to ZZ */
+ env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA {}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "ZZ", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class ZZ {} \n"+ //$NON-NLS-1$
+ "class AZ {}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+
+ /* Move AZ from ZZ to AA */
+ env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA {} \n"+ //$NON-NLS-1$
+ "class AZ {}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "ZZ", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class ZZ {}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ public void testMoveMemberType() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA {} \n"+ //$NON-NLS-1$
+ "class AZ {static class M{}}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "AB", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "import p.AZ.*; \n"+ //$NON-NLS-1$
+ "import p.ZA.*; \n"+ //$NON-NLS-1$
+ "public class AB extends M {}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "ZZ", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class ZZ {} \n"+ //$NON-NLS-1$
+ "class ZA {}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingOnlySpecificProblemsFor(
+ root,
+ new Problem[]{
+ new Problem("", "The import p.ZA is never used", new Path("/Project/src/p/AB.java"), 35, 39, CategorizedProblem.CAT_UNNECESSARY_CODE, IMarker.SEVERITY_WARNING), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ });
+
+ /* Move M from AA to ZZ */
+ env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA {} \n"+ //$NON-NLS-1$
+ "class AZ {}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "ZZ", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class ZZ {} \n"+ //$NON-NLS-1$
+ "class ZA {static class M{}}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingOnlySpecificProblemsFor(
+ root,
+ new Problem[]{
+ new Problem("", "The import p.AZ is never used", new Path("/Project/src/p/AB.java"), 19, 23, CategorizedProblem.CAT_UNNECESSARY_CODE, IMarker.SEVERITY_WARNING), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ });
+
+ /* Move M from ZZ to AA */
+ env.addClass(root, "p", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class AA {} \n"+ //$NON-NLS-1$
+ "class AZ {static class M{}}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "ZZ", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class ZZ {} \n"+ //$NON-NLS-1$
+ "class ZA {}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingOnlySpecificProblemsFor(
+ root,
+ new Problem[]{
+ new Problem("", "The import p.ZA is never used", new Path("/Project/src/p/AB.java"), 35, 39, CategorizedProblem.CAT_UNNECESSARY_CODE, IMarker.SEVERITY_WARNING), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ });
+ env.removeProject(projectPath);
+ }
+
+ public void testMovePackage() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath[] exclusionPatterns = new Path[] {new Path("src2/")}; //$NON-NLS-1$
+ IPath src1 = env.addPackageFragmentRoot(projectPath, "src1", exclusionPatterns, null); //$NON-NLS-1$
+ IPath src2 = env.addPackageFragmentRoot(projectPath, "src1/src2"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(src1, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class A {}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.removePackage(src1, "p"); //$NON-NLS-1$
+ env.addClass(src2, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class A {}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ public void testMovePackage2() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath src = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ IPath other = env.addFolder(projectPath, "other"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath classA = env.addClass(src, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class A extends Missing {}"); //$NON-NLS-1$
+ IPath classB = env.addClass(src, "p.q", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p.q; \n"+ //$NON-NLS-1$
+ "public class B extends Missing {}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingSpecificProblemFor(
+ classA,
+ new Problem("", "Missing cannot be resolved to a type", new Path("/Project/src/p/A.java"), 35, 42, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ );
+ expectingSpecificProblemFor(
+ classB,
+ new Problem("", "Missing cannot be resolved to a type", new Path("/Project/src/p/q/B.java"), 37, 44, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ );
+
+ try {
+ IProject p = env.getProject(projectPath);
+ IFolder pFolder = p.getWorkspace().getRoot().getFolder(classA.removeLastSegments(1));
+ pFolder.move(other.append("p"), true, false, null);
+ } catch (CoreException e) {
+ env.handle(e);
+ }
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ public void testMemberTypeFromClassFile() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class A extends Z {M[] m;}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class B {A a; E e; \n"+ //$NON-NLS-1$
+ "void foo() { System.out.println(a.m); }}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "E", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class E extends Z { \n"+ //$NON-NLS-1$
+ "void foo() { System.out.println(new M()); }}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class Z {static class M {}}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class B {A a; E e; \n"+ //$NON-NLS-1$
+ "void foo( ) { System.out.println(a.m); }}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "E", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class E extends Z { \n"+ //$NON-NLS-1$
+ "void foo( ) { System.out.println(new M()); }}"); //$NON-NLS-1$
+
+ env.addClass(root, "p", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class Z { static class M {} }"); //$NON-NLS-1$
+
+ int previous = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 1; // reduce the lot size
+ incrementalBuild(projectPath);
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = previous;
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=372418
+ public void testMemberTypeOfOtherProject() throws JavaModelException {
+ IPath projectPath1 = env.addProject("Project1", "1.5"); //$NON-NLS-1$ //$NON-NLS-2$
+ env.addExternalJars(projectPath1, Util.getJavaClassLibs());
+
+ IPath projectPath2 = env.addProject("Project2", "1.5"); //$NON-NLS-1$ //$NON-NLS-2$
+ env.addExternalJars(projectPath2, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath1, ""); //$NON-NLS-1$
+
+ IPath root1 = env.addPackageFragmentRoot(projectPath1, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath1, "bin"); //$NON-NLS-1$
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath2, ""); //$NON-NLS-1$
+
+ IPath root2 = env.addPackageFragmentRoot(projectPath2, "src"); //$NON-NLS-1$
+ IPath output2 = env.setOutputFolder(projectPath2, "bin"); //$NON-NLS-1$
+
+ env.addClassFolder(projectPath1, output2, true);
+ env.addRequiredProject(projectPath2, projectPath1);
+
+ env.addClass(root1, "pB", "BaseClass", //$NON-NLS-1$ //$NON-NLS-2$
+ "package pB; \n"+ //$NON-NLS-1$
+ "public class BaseClass {\n" + //$NON-NLS-1$
+ " public static class Builder {\n"+ //$NON-NLS-1$
+ " public Builder(T t) {\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n");//$NON-NLS-1$
+
+ env.addClass(root1, "pR", "ReferencingClass", //$NON-NLS-1$ //$NON-NLS-2$
+ "package pR; \n"+ //$NON-NLS-1$
+ "import pD.DerivedClass.Builder;\n"+ //$NON-NLS-1$
+ "public class ReferencingClass {\n" + //$NON-NLS-1$
+ " Builder builder = new Builder(null);\n" + //$NON-NLS-1$
+ "}\n"); //$NON-NLS-1$
+
+ env.addClass(root2, "pD", "DerivedClass", //$NON-NLS-1$ //$NON-NLS-2$
+ "package pD; \n"+ //$NON-NLS-1$
+ "public class DerivedClass extends pB.BaseClass {\n" + //$NON-NLS-1$
+ " public static class Builder extends pB.BaseClass.Builder {\n"+ //$NON-NLS-1$
+ " public Builder(T t) {\n" + //$NON-NLS-1$
+ " super(t);\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n"); //$NON-NLS-1$
+
+ int previous = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
+ fullBuild();
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 1; // reduce the lot size
+ cleanBuild();
+ fullBuild();
+ cleanBuild("Project1"); //$NON-NLS-1$
+ fullBuild(projectPath1);
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = previous;
+ expectingNoProblems();
+ env.removeProject(projectPath1);
+ }
+
+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=377401
+ public void test$InTypeName() throws JavaModelException {
+ IPath projectPath1 = env.addProject("Project1", "1.5"); //$NON-NLS-1$ //$NON-NLS-2$
+ env.addExternalJars(projectPath1, Util.getJavaClassLibs());
+
+ IPath projectPath2 = env.addProject("Project2", "1.5"); //$NON-NLS-1$ //$NON-NLS-2$
+ env.addExternalJars(projectPath2, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath1, ""); //$NON-NLS-1$
+
+ IPath root1 = env.addPackageFragmentRoot(projectPath1, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath1, "bin"); //$NON-NLS-1$
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath2, ""); //$NON-NLS-1$
+
+ IPath root2 = env.addPackageFragmentRoot(projectPath2, "src"); //$NON-NLS-1$
+ IPath output2 = env.setOutputFolder(projectPath2, "bin"); //$NON-NLS-1$
+
+ env.addClassFolder(projectPath1, output2, true);
+ env.addRequiredProject(projectPath2, projectPath1);
+
+ env.addClass(root1, "pB", "Builder$a", //$NON-NLS-1$ //$NON-NLS-2$
+ "package pB; \n"+ //$NON-NLS-1$
+ "public class Builder$a {\n" + //$NON-NLS-1$
+ " public Builder$a(T t) {\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n");//$NON-NLS-1$
+
+ env.addClass(root1, "pR", "ReferencingClass", //$NON-NLS-1$ //$NON-NLS-2$
+ "package pR; \n"+ //$NON-NLS-1$
+ "import pD.DerivedClass$a;\n"+ //$NON-NLS-1$
+ "public class ReferencingClass {\n" + //$NON-NLS-1$
+ " DerivedClass$a builder = new DerivedClass$a(null);\n" + //$NON-NLS-1$
+ "}\n"); //$NON-NLS-1$
+
+ env.addClass(root2, "pD", "DerivedClass$a", //$NON-NLS-1$ //$NON-NLS-2$
+ "package pD; \n"+ //$NON-NLS-1$
+ "public class DerivedClass$a extends pB.Builder$a {\n" + //$NON-NLS-1$
+ " public DerivedClass$a(T t) {\n" + //$NON-NLS-1$
+ " super(t);\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}\n"); //$NON-NLS-1$
+
+ int previous = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
+ fullBuild();
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 1; // reduce the lot size
+ cleanBuild();
+ fullBuild();
+ cleanBuild("Project1"); //$NON-NLS-1$
+ fullBuild(projectPath1);
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = previous;
+ expectingNoProblems();
+ env.removeProject(projectPath1);
+ }
+
+ // http://dev.eclipse.org/bugs/show_bug.cgi?id=27658
+ public void testObjectWithSuperInterfaces() throws JavaModelException {
+ try {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "java.lang", "Object", //$NON-NLS-1$ //$NON-NLS-2$
+ "package java.lang; \n"+ //$NON-NLS-1$
+ "public class Object implements I {} \n"+ //$NON-NLS-1$
+ "interface I {} \n"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+
+ expectingOnlySpecificProblemsFor(
+ root,
+ new Problem[]{
+ new Problem("", "The type java.lang.Object cannot have a superclass or superinterfaces", new Path("/Project/src/java/lang/Object.java"), 33, 39, CategorizedProblem.CAT_INTERNAL, IMarker.SEVERITY_ERROR), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ });
+
+ env.addClass(root, "p", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class X {}\n"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+
+ expectingOnlySpecificProblemsFor(
+ root,
+ new Problem[]{
+ new Problem("", "The type java.lang.Object cannot have a superclass or superinterfaces", new Path("/Project/src/java/lang/Object.java"), 33, 39, CategorizedProblem.CAT_INTERNAL, IMarker.SEVERITY_ERROR), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ });
+
+ env.addClass(root, "p", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p; \n"+ //$NON-NLS-1$
+ "public class Y extends X {}\n"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+
+ expectingOnlySpecificProblemsFor(
+ root,
+ new Problem[]{
+ new Problem("", "The type java.lang.Object cannot have a superclass or superinterfaces", new Path("/Project/src/java/lang/Object.java"), 33, 39, CategorizedProblem.CAT_INTERNAL, IMarker.SEVERITY_ERROR), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ });
+ env.removeProject(projectPath);
+
+ } catch(StackOverflowError e){
+ assertTrue("Infinite loop in cycle detection", false); //$NON-NLS-1$
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Bugs 6461
+ * TODO excluded test
+ */
+ public void _testWrongCompilationUnitLocation() throws JavaModelException {
+ //----------------------------
+ // Step 1
+ //----------------------------
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ IPath bin = env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+ IPath x = env.addClass(root, "", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class X {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+
+ fullBuild();
+ expectingNoProblems();
+ expectingPresenceOf(bin.append("X.class")); //$NON-NLS-1$
+
+ //----------------------------
+ // Step 2
+ //----------------------------
+ env.addClass(root, "", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild();
+ expectingProblemsFor(x, "???");
+ expectingNoPresenceOf(bin.append("X.class")); //$NON-NLS-1$
+ env.removeProject(projectPath);
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=100631
+ public void testMemberTypeCollisionWithBinary() throws JavaModelException {
+ int max = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
+ try {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class A {\n"+ //$NON-NLS-1$
+ " Object foo(B b) { return b.i; }\n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+ env.addClass(root, "", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class B {\n"+ //$NON-NLS-1$
+ " I.InnerType i;\n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+ env.addClass(root, "", "I", //$NON-NLS-1$ //$NON-NLS-2$
+ "public interface I {\n"+ //$NON-NLS-1$
+ " interface InnerType {}\n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 1;
+
+ env.addClass(root, "", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class A {\n"+ //$NON-NLS-1$
+ " Object foo(B b) { return b.i; }\n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+ env.addClass(root, "", "I", //$NON-NLS-1$ //$NON-NLS-2$
+ "public interface I {\n"+ //$NON-NLS-1$
+ " interface InnerType {}\n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ } finally {
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = max;
+ }
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=191739
+ public void testMemberTypeCollisionWithBinary2() throws JavaModelException {
+ int max = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
+ try {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath src1 = env.addPackageFragmentRoot(projectPath, "src1"); //$NON-NLS-1$
+ IPath bin1 = env.setOutputFolder(projectPath, "bin1"); //$NON-NLS-1$
+
+ env.addClass(src1, "p1", "NoSource", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1; \n"+
+ "import p2.Foo;\n"+ //$NON-NLS-1$
+ "public class NoSource {\n"+ //$NON-NLS-1$
+ " public NoSource(Foo.Bar b) {}\n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ IPath src2 = env.addPackageFragmentRoot(projectPath, "src2", null, "bin2"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(src2, "p2", "Foo", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2; \n"+
+ "public class Foo {\n"+ //$NON-NLS-1$
+ " public static class Bar {\n" + //$NON-NLS-1$
+ " public static Bar LocalBar = new Bar();\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ env.addClass(src2, "p2", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2; \n"+
+ "import p1.NoSource;\n"+ //$NON-NLS-1$
+ "import p2.Foo.Bar;\n"+ //$NON-NLS-1$
+ "public class Test {\n"+ //$NON-NLS-1$
+ " NoSource nosrc = new NoSource(Bar.LocalBar);\n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.removePackageFragmentRoot(projectPath, "src1"); //$NON-NLS-1$
+ env.addClassFolder(projectPath, bin1, false);
+
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 1;
+
+ env.addClass(src2, "p2", "Test", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2; \n"+
+ "import p1.NoSource;\n"+ //$NON-NLS-1$
+ "import p2.Foo.Bar;\n"+ //$NON-NLS-1$
+ "public class Test {\n"+ //$NON-NLS-1$
+ " NoSource nosrc = new NoSource(Bar.LocalBar);\n" + //$NON-NLS-1$
+ "}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ } finally {
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = max;
+ }
+ }
+
+
+ public void test129316() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, ""); //$NON-NLS-1$
+
+ IPath yPath = env.addClass(projectPath, "p", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;\n" +
+ "public class Y extends Z {}"); //$NON-NLS-1$
+
+ env.addClass(projectPath, "p", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;\n" +
+ "public class Z {}"); //$NON-NLS-1$
+
+ env.addClass(projectPath, "", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "import p.Y;\n" +
+ "public class X {\n" +
+ " boolean b(Object o) {\n" +
+ " return o instanceof Y;\n" +
+ " }\n" +
+ "}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(projectPath, "p", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;\n" +
+ "public class Y extends Zork {}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(yPath, new Problem("Y", "Zork cannot be resolved to a type", yPath, 34, 38, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ IPath xPath = env.addClass(projectPath, "", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class X {\n" +
+ " boolean b(Object o) {\n" +
+ " return o instanceof p.Y;\n" +
+ " }\n" +
+ "}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(yPath, new Problem("Y", "Zork cannot be resolved to a type", yPath, 34, 38, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingNoProblemsFor(xPath);
+ env.removeProject(projectPath);
+ }
+
+ public void testSecondaryType() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "", "AB", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class AB { AZ z = new AA();}"); //$NON-NLS-1$
+
+ env.addClass(root, "", "AA", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class AA extends AZ {} \n"+ //$NON-NLS-1$
+ "class AZ {}"); //$NON-NLS-1$
+
+ int max = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
+ try {
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 1;
+ fullBuild(projectPath);
+ } finally {
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = max;
+ }
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+ // http://dev.eclipse.org/bugs/show_bug.cgi?id=196200 - variation
+ public void testMissingType001() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath xPath = env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo(p2.Y y) { \n" + //$NON-NLS-1$
+ " y.bar(null);" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ " void X() {}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ IPath yPath = env.addClass(root, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Y {\n"+ //$NON-NLS-1$
+ " public void bar(Z z) {}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ fullBuild(projectPath);
+ expectingSpecificProblemFor(xPath, new Problem("X", "This method has a constructor name", xPath, 73, 76, CategorizedProblem.CAT_CODE_STYLE, IMarker.SEVERITY_WARNING)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(yPath, new Problem("Y", "Z cannot be resolved to a type", yPath, 46, 47, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p2", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Z {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(xPath, new Problem("X", "This method has a constructor name", xPath, 73, 76, CategorizedProblem.CAT_CODE_STYLE, IMarker.SEVERITY_WARNING)); //$NON-NLS-1$ //$NON-NLS-2$
+ env.removeProject(projectPath);
+ }
+
+ // http://dev.eclipse.org/bugs/show_bug.cgi?id=196200 - variation
+ public void testMissingType002() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath yPath = env.addClass(root, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Y {\n"+ //$NON-NLS-1$
+ " public void bar(Z z) {}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ fullBuild(projectPath);
+ expectingSpecificProblemFor(yPath, new Problem("Y", "Z cannot be resolved to a type", yPath, 46, 47, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ IPath xPath = env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo(p2.Y y) { \n" + //$NON-NLS-1$
+ " y.bar(null);" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ " void X() {}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(xPath, new Problem("X", "This method has a constructor name", xPath, 73, 76, CategorizedProblem.CAT_CODE_STYLE, IMarker.SEVERITY_WARNING)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(yPath, new Problem("Y", "Z cannot be resolved to a type", yPath, 46, 47, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p2", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Z {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(xPath, new Problem("X", "This method has a constructor name", xPath, 73, 76, CategorizedProblem.CAT_CODE_STYLE, IMarker.SEVERITY_WARNING)); //$NON-NLS-1$ //$NON-NLS-2$
+ env.removeProject(projectPath);
+ }
+
+ // http://dev.eclipse.org/bugs/show_bug.cgi?id=196200 - variation
+ public void testMissingType003() throws JavaModelException {
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ fullBuild(projectPath);
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath yPath = env.addClass(root, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Y {\n"+ //$NON-NLS-1$
+ " public void bar(p1.Z z) {}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ fullBuild(projectPath);
+ expectingSpecificProblemFor(yPath, new Problem("Y", "p1 cannot be resolved to a type", yPath, 46, 48, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ IPath xPath = env.addClass(root, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void foo(p2.Y y) { \n" + //$NON-NLS-1$
+ " y.bar(null);" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ " void X() {}\n" + //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(xPath, new Problem("X", "This method has a constructor name", xPath, 73, 76, CategorizedProblem.CAT_CODE_STYLE, IMarker.SEVERITY_WARNING)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(yPath, new Problem("Y", "p1.Z cannot be resolved to a type", yPath, 46, 50, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(root, "p1", "Z", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class Z {\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(xPath, new Problem("X", "This method has a constructor name", xPath, 73, 76, CategorizedProblem.CAT_CODE_STYLE, IMarker.SEVERITY_WARNING)); //$NON-NLS-1$ //$NON-NLS-2$
+ env.removeProject(projectPath);
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=334377
+ public void testBug334377() throws JavaModelException {
+ int max = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
+ Hashtable options = null;
+ try {
+ options = JavaCore.getOptions();
+ Hashtable newOptions = JavaCore.getOptions();
+ newOptions.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
+ newOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
+ newOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
+ JavaCore.setOptions(newOptions);
+
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(root, "", "Upper",
+ "public abstract class Upper {\n" +
+ " public static enum Mode {IN,OUT;}\n" +
+ "}\n");
+ env.addClass(root, "", "Lower",
+ "public class Lower extends Upper {};\n");
+ env.addClass(root, "", "Bug",
+ "public class Bug {\n" +
+ " Upper.Mode m1;\n" +
+ " void usage(){\n" +
+ " Lower.Mode m3;\n" +
+ " if (m1 == null){\n" +
+ " m3 = Lower.Mode.IN;\n" +
+ " } else {\n" +
+ " m3 = m1;\n" +
+ " }\n" +
+ " Lower.Mode m2 = (m1 == null ? Lower.Mode.IN : m1);\n" +
+ " System.out.println(m2);\n" +
+ " System.out.println(m3);\n" +
+ " }\n" +
+ "}\n");
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+ env.addClass(root, "", "Bug",
+ "public class Bug {\n" +
+ " Upper.Mode m1;\n" +
+ " void usage(){\n" +
+ " Lower.Mode m3;\n" +
+ " if (m1 == null){\n" +
+ " m3 = Lower.Mode.IN;\n" +
+ " } else {\n" +
+ " m3 = m1;\n" +
+ " }\n" +
+ " Lower.Mode m2 = (m1 == null ? Lower.Mode.IN : m1);\n" +
+ " System.out.println(m2);\n" +
+ " System.out.println(m3);\n" +
+ " }\n" +
+ "}\n");
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ } finally {
+ org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = max;
+ JavaCore.setOptions(options);
+ }
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450
+ // Incremental build should not generate buildpath error
+ // NOT generated by full build.
+ public void testBug364450() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath wPath = env.addClass(projectPath, "w", "W", //$NON-NLS-1$ //$NON-NLS-2$
+ "package w;\n" +
+ "public class W {\n" +
+ " private w.I i;}"); //$NON-NLS-1$
+
+ IPath aPath = env.addClass(projectPath, "a", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package a;\n" +
+ "import w.I;\n" +
+ "import w.W;\n" +
+ "public class A {}"); //$NON-NLS-1$
+ env.waitForManualRefresh();
+ fullBuild(projectPath);
+ env.waitForAutoBuild();
+ expectingSpecificProblemFor(wPath, new Problem("W", "w.I cannot be resolved to a type", wPath, 37, 40, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(aPath, new Problem("A", "The import w.I cannot be resolved", aPath, 18, 21, CategorizedProblem.CAT_IMPORT, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ aPath = env.addClass(projectPath, "a", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package a;\n" +
+ "import w.I;\n" +
+ "import w.W;\n" +
+ "public class A {}"); //$NON-NLS-1$
+
+ env.waitForManualRefresh();
+ incrementalBuild(projectPath);
+ env.waitForAutoBuild();
+ expectingSpecificProblemFor(aPath, new Problem("A", "The import w.I cannot be resolved", aPath, 18, 21, CategorizedProblem.CAT_IMPORT, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ env.removeProject(projectPath);
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=520640
+ public void testRemovePackageInDependencyProject() throws JavaModelException {
+ IPath projectPath1 = env.addProject("Project1");
+ env.addExternalJars(projectPath1, Util.getJavaClassLibs());
+
+ IPath projectPath2 = env.addProject("Project2");
+ env.addExternalJars(projectPath2, Util.getJavaClassLibs());
+
+
+ env.addRequiredProject(projectPath1, projectPath2);
+
+ env.addPackage(projectPath2, "emptypackage");
+
+ fullBuild();
+ expectingNoProblems();
+
+ env.removePackage(projectPath2, "emptypackage");
+ incrementalBuild();
+ expectingNoProblems();
+
+ env.removeProject(projectPath2);
+ env.removeProject(projectPath1);
+ }
+
+ public void testBug526376() throws JavaModelException {
+ IPath projectPath = env.addProject("Project");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ env.addClass(root, "p", "A",
+ "package p; \n"+
+ "public class A extends B {} \n");
+
+ fullBuild(projectPath);
+
+ env.addClass(root, "p", "B",
+ "package p; \n"+
+ "public class B {}\n");
+
+ incrementalBuild(projectPath);
+ expectingCompilingOrder(new String[] { "/Project/src/p/B.java", "/Project/src/p/A.java" });
+ expectingNoProblems();
+ env.removeProject(projectPath);
+ }
+
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests18.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests18.java
new file mode 100644
index 0000000000..1dd42e9d83
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests18.java
@@ -0,0 +1,813 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Test;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.osgi.framework.Bundle;
+
+public class IncrementalTests18 extends BuilderTests {
+ static {
+// TESTS_NAMES = new String[] { "testBug481276b" };
+ }
+ public IncrementalTests18(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return AbstractCompilerTest.buildUniqueComplianceTestSuite(IncrementalTests18.class, ClassFileConstants.JDK1_8);
+ }
+
+ private void setupProjectForNullAnnotations() throws IOException, JavaModelException {
+ // add the org.eclipse.jdt.annotation library (bin/ folder or jar) to the project:
+ 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();
+ IJavaProject javaProject = env.getJavaProject("Project");
+ IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
+ int len = rawClasspath.length;
+ System.arraycopy(rawClasspath, 0, rawClasspath = new IClasspathEntry[len+1], 0, len);
+ rawClasspath[len] = JavaCore.newLibraryEntry(new Path(annotationsLib), null, null);
+ javaProject.setRawClasspath(rawClasspath, null);
+
+ javaProject.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=423122, [1.8] Missing incremental build dependency from lambda expression to functional interface.
+ public void test423122() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ env.addClass(root, "p", "I",
+ "package p; \n"+
+ "public interface I { void foo(); } \n"
+ );
+ env.addClass(root, "p", "X",
+ "package p; \n"+
+ "public class X { I i = () -> {}; } \n"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p", "I",
+ "package p; \n"+
+ "public interface I { } \n"
+ );
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : The target type of this expression must be a functional interface [ resource : range : <35,40> category : <40> severity : <2>]"
+ );
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=423122, [1.8] Missing incremental build dependency from lambda expression to functional interface.
+ public void test423122a() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ env.addClass(root, "test1", "I",
+ "package test1;\n" +
+ "public interface I {\n" +
+ " int method(int a); // change argument type to Object\n" +
+ "}\n"
+ );
+ env.addClass(root, "test1", "E",
+ "package test1;\n" +
+ "public class E {\n" +
+ " void take(I i) {\n" +
+ " }\n" +
+ "}\n"
+ );
+ env.addClass(root, "test1", "Ref",
+ "package test1;\n" +
+ "public class Ref {\n" +
+ " void foo(E e) {\n" +
+ " e.take((x) -> x+2); // not recompiled when I#method changed\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "test1", "I",
+ "package test1;\n" +
+ "public interface I {\n" +
+ " int method(Object a); // change argument type to Object\n" +
+ "}\n"
+ );
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : The operator + is undefined for the argument type(s) Object, int [ resource : range : <76,79> category : <60> severity : <2>]"
+ );
+ env.addClass(root, "test1", "I",
+ "package test1;\n" +
+ "public interface I {\n" +
+ " int method(int a); // change argument type back to int\n" +
+ "}\n"
+ );
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=427105, [1.8][builder] Differences between incremental and full builds in method contract verification in the presence of type annotations
+ public void test427105() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ env.addClass(root, "", "X",
+ "import java.util.List;\n" +
+ "public class X implements I {\n" +
+ " public void f(List x, List ls) { \n" +
+ " }\n" +
+ "}\n"
+ );
+ env.addClass(root, "", "I",
+ "import java.util.List;\n" +
+ "public interface I {\n" +
+ " void f(@T List x, List ls);\n" +
+ "}\n"
+ );
+ env.addClass(root, "", "T",
+ "import java.lang.annotation.ElementType;\n" +
+ "import java.lang.annotation.Target;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "public @interface T {\n" +
+ "}\n"
+ );
+
+ // force annotation encoding into bindings which is necessary to reproduce.
+ env.getJavaProject("Project").setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
+
+ fullBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : List is a raw type. References to generic type List should be parameterized [ resource : range : <55,59> category : <130> severity : <1>]\n" +
+ "Problem : List is a raw type. References to generic type List should be parameterized [ resource : range : <68,72> category : <130> severity : <1>]"
+ );
+ env.addClass(root, "", "X",
+ "import java.util.List;\n" +
+ "public class X implements I {\n" +
+ " public void f(List x, List ls) { \n" +
+ " }\n" +
+ "}\n"
+ );
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : List is a raw type. References to generic type List should be parameterized [ resource : range : <55,59> category : <130> severity : <1>]\n" +
+ "Problem : List is a raw type. References to generic type List should be parameterized [ resource : range : <68,72> category : <130> severity : <1>]"
+ );
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=427105, [1.8][builder] Differences between incremental and full builds in method contract verification in the presence of type annotations
+ public void test427105a() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ env.addClass(root, "", "X",
+ "import java.util.List;\n" +
+ "public class X implements I {\n" +
+ " public void f(List x, List ls) { \n" +
+ " }\n" +
+ "}\n"
+ );
+ env.addClass(root, "", "I",
+ "import java.util.List;\n" +
+ "public interface I {\n" +
+ " void f(@T List x, List ls);\n" +
+ "}\n"
+ );
+ env.addClass(root, "", "T",
+ "import java.lang.annotation.ElementType;\n" +
+ "import java.lang.annotation.Target;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "public @interface T {\n" +
+ "}\n"
+ );
+
+ // force annotation encoding into bindings which is necessary to reproduce.
+ env.getJavaProject("Project").setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
+
+ fullBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : List is a raw type. References to generic type List should be parameterized [ resource : range : <55,59> category : <130> severity : <1>]\n" +
+ "Problem : List is a raw type. References to generic type List should be parameterized [ resource : range : <68,72> category : <130> severity : <1>]"
+ );
+ env.addClass(root, "", "X",
+ "import java.util.List;\n" +
+ "public class X implements I {\n" +
+ " public void f(@T List x, List ls) { \n" +
+ " }\n" +
+ "}\n"
+ );
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : List is a raw type. References to generic type List should be parameterized [ resource : range : <55,59> category : <130> severity : <1>]\n" +
+ "Problem : List is a raw type. References to generic type List should be parameterized [ resource : range : <71,75> category : <130> severity : <1>]"
+ );
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428071, [1.8][compiler] Bogus error about incompatible return type during override
+ public void test428071() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ env.addClass(root, "", "K1",
+ "import java.util.List;\n" +
+ "import java.util.Map;\n" +
+ "interface K1 {\n" +
+ " public Map get();\n" +
+ "}\n"
+ );
+ env.addClass(root, "", "K",
+ "import java.util.List;\n" +
+ "import java.util.Map;\n" +
+ "public class K implements K1 {\n" +
+ " public Map get() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ );
+ env.getJavaProject("Project").setOption(JavaCore.COMPILER_PB_RAW_TYPE_REFERENCE, JavaCore.IGNORE);
+ fullBuild(projectPath);
+ expectingNoProblems();
+ env.addClass(root, "", "K",
+ "import java.util.List;\n" +
+ "import java.util.Map;\n" +
+ "public class K implements K1 {\n" +
+ " public Map get() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ );
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=430425, [1.8][compiler] Type mismatch: cannot convert from StyleConverter to StyleConverter
+ public void test430425() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ String jreDirectory = Util.getJREDirectory();
+ String jfxJar = Util.toNativePath(jreDirectory + "/lib/ext/jfxrt.jar");
+ File file = new File(jfxJar);
+ if (file.exists())
+ env.addExternalJars(projectPath, Util.concatWithClassLibs(jfxJar, false));
+ else
+ return;
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ env.addClass(root, "javafx.css", "StyleConverter",
+ "package javafx.css;\n" +
+ "import com.sun.javafx.css.converters.InsetsConverter;\n" +
+ "import javafx.geometry.Insets;\n" +
+ "public class StyleConverter {\n" +
+ " public static StyleConverter getInsetsConverter() {\n" +
+ " return InsetsConverter.getInstance();\n" +
+ " }\n" +
+ " void fred5555() {\n" +
+ " }\n" +
+ "}\n"
+ );
+ env.addClass(root, "com.sun.javafx.css.converters", "InsetsConverter",
+ "package com.sun.javafx.css.converters;\n" +
+ "import com.sun.javafx.css.StyleConverterImpl;\n" +
+ "import javafx.css.ParsedValue;\n" +
+ "import javafx.css.StyleConverter;\n" +
+ "import javafx.geometry.Insets;\n" +
+ "public final class InsetsConverter extends StyleConverterImpl {\n" +
+ " public static StyleConverter getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ );
+ env.addClass(root, "javafx.css", "ParsedValue",
+ "package javafx.css;\n" +
+ "public class ParsedValue {\n" +
+ "}\n"
+ );
+ env.getJavaProject("Project").setOption(JavaCore.COMPILER_PB_RAW_TYPE_REFERENCE, JavaCore.IGNORE);
+ fullBuild(projectPath);
+ expectingNoProblems();
+ env.addClass(root, "javafx.css", "StyleConverter",
+ "package javafx.css;\n" +
+ "import com.sun.javafx.css.converters.InsetsConverter;\n" +
+ "import javafx.geometry.Insets;\n" +
+ "public class StyleConverter {\n" +
+ " public static StyleConverter getInsetsConverter() {\n" +
+ " return InsetsConverter.getInstance();\n" +
+ " }\n" +
+ " void fred555() {\n" +
+ " }\n" +
+ "}\n"
+ );
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=435544, [compiler][null] Enum constants not recognised as being NonNull (take2)
+ public void test435544() throws JavaModelException, IOException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ setupProjectForNullAnnotations();
+ env.addClass(root, "p", "Y",
+ "package p; \n" +
+ "public enum Y {\n" +
+ " A,\n" +
+ " B\n" +
+ "}\n" +
+ "\n"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "p", "X",
+ "package p; \n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "public class X {\n" +
+ " @NonNull\n" +
+ " public Y y = Y.A; // warning without fix\n" +
+ " void foo(@NonNull Y y) {}\n" +
+ " void bar() {\n" +
+ " foo(Y.A); // warning without fix\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=442452, [compiler][regression] Bogus error: The interface Comparable cannot be implemented more than once with different arguments
+ public void testBug442452() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(projectPath, "", "Entity", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class Entity implements IEntity {\n" +
+ " public int compareTo(IBasicItem o) {\n" +
+ " return 0;\n" +
+ " }\n" +
+ "}\n"); //$NON-NLS-1$
+
+ env.addClass(projectPath, "", "IEntity", //$NON-NLS-1$ //$NON-NLS-2$
+ "public interface IEntity> extends IBasicItem {\n" +
+ "}\n"); //$NON-NLS-1$
+
+ env.addClass(projectPath, "", "IBasicItem", //$NON-NLS-1$ //$NON-NLS-2$
+ "public interface IBasicItem extends Comparable {\n" +
+ "}\n"); //$NON-NLS-1$
+
+ env.addClass(projectPath, "", "IAdvancedItem", //$NON-NLS-1$ //$NON-NLS-2$
+ "public interface IAdvancedItem extends Comparable {\n" +
+ "}\n"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(projectPath, "", "Entity", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class Entity implements IEntity, IAdvancedItem {\n" +
+ " public int compareTo(IBasicItem o) {\n" +
+ " return 0;\n" +
+ " }\n" +
+ "}\n"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=442755,
+ // [compiler] NPE at ProblemHandler.handle
+ public void testBug442755() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "bin");
+ env.addClass(projectPath, "", "Z",
+ "public interface Z {}\n");
+ fullBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : X cannot be resolved to a type [ resource : " +
+ " range : <31,32> category : <40> severity : <2>]\n" +
+ "Problem : Y cannot be resolved to a type [ resource : " +
+ " range : <45,46> category : <40> severity : <2>]");
+ env.addClass(projectPath, "", "Unmarshaller", //$NON-NLS-1$ //$NON-NLS-2$
+ "public abstract class Unmarshaller {\n" +
+ " public CONTEXT getContext() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n");
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : The project was not built since its build path is incomplete." +
+ " Cannot find the class file for Y. Fix the build path then try building" +
+ " this project [ resource : range : <-1,-1> category : <10> severity : <2>]\n" +
+ "Problem : The type Y cannot be resolved. It is indirectly referenced from" +
+ " required .class files [ resource : range : <0,1> category : <10> severity : <2>]");
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=442755,
+ // [compiler] NPE at ProblemHandler.handle
+ // Simplified test case.
+ public void testBug442755a() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "bin");
+ env.addClass(projectPath, "", "Z",
+ "public class Z {}\n");
+ fullBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : Y cannot be resolved to a type [ resource : " +
+ " range : <27,28> category : <40> severity : <2>]");
+ env.addClass(projectPath, "", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "public class X {}\n");
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : The project was not built since its build path is incomplete." +
+ " Cannot find the class file for Y. Fix the build path then try building" +
+ " this project [ resource : range : <-1,-1> category : <10> severity : <2>]\n" +
+ "Problem : The type Y cannot be resolved. It is indirectly referenced from" +
+ " required .class files [ resource : range : <0,1> category : <10> severity : <2>]");
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=445049,
+ // [compiler] java.lang.ClassCastException: org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding
+ // cannot be cast to org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding
+ public void test445049() throws JavaModelException, IOException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ setupProjectForNullAnnotations();
+ env.addClass(root, "", "I",
+ "public interface I { int f = 0;}");
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(root, "", "X", "class X implements I { int i = I.super.f;}");
+
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : No enclosing instance of the type I is accessible in scope [" +
+ " resource : range : <31,38> category : <40> severity : <2>]");
+ }
+
+ public void testBug481276a() throws Exception {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ setupProjectForNullAnnotations();
+
+ // clean status from https://bugs.eclipse.org/bugs/attachment.cgi?id=257687
+ env.addClass(root, "testNullAnnotations", "package-info",
+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+ "package testNullAnnotations;\n");
+ env.addClass(root, "testNullAnnotations", "NonNullUtils",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "\n" +
+ "public final class NonNullUtils {\n" +
+ "\n" +
+ " public static T[] checkNotNull(T @Nullable [] array) {\n" +
+ " if (array == null) {\n" +
+ " throw new NullPointerException();\n" +
+ " }\n" +
+ " return array;\n" +
+ " }\n" +
+ "}\n");
+ env.addClass(root, "testNullAnnotations", "Snippet",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import static testNullAnnotations.NonNullUtils.checkNotNull;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "public class Snippet {\n" +
+ " @SuppressWarnings(\"unused\")\n" +
+ " public void foo() {\n" +
+ " @NonNull Object @Nullable [] objects = null;\n" +
+ " @NonNull Object @NonNull [] checked3 = checkNotNull(objects); \n" +
+ " }\n" +
+ "}\n");
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ // add an error by removing the necessary @Nullable annotation:
+ env.addClass(root, "testNullAnnotations", "NonNullUtils",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "public final class NonNullUtils {\n" +
+ "\n" +
+ " public static T[] checkNotNull(T [] array) {\n" +
+ " if (array == null) {\n" +
+ " throw new NullPointerException();\n" +
+ " }\n" +
+ " return array;\n" +
+ " }\n" +
+ "}\n");
+
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : Dead code [" +
+ " resource : range : <145,202> category : <90> severity : <1>]\n" +
+ "Problem : Null type mismatch (type annotations): required '@NonNull Object @NonNull[]' but this expression has type '@NonNull Object @Nullable[]' [" +
+ " resource : range : <316,323> category : <90> severity : <2>]");
+ }
+
+ public void testBug481276b() throws Exception {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ setupProjectForNullAnnotations();
+ // clean status:
+ env.addClass(root, "testNullAnnotations", "package-info",
+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+ "package testNullAnnotations;\n");
+ env.addClass(root, "testNullAnnotations", "NonNullUtils",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "\n" +
+ "public final class NonNullUtils {\n" +
+ "\n" +
+ " public static <@Nullable T> T[] checkNotNull(T @Nullable[] array) {\n" +
+ " if (array == null) {\n" +
+ " throw new NullPointerException();\n" +
+ " }\n" +
+ " return array;\n" +
+ " }\n" +
+ "}\n");
+ env.addClass(root, "testNullAnnotations", "Snippet",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import static testNullAnnotations.NonNullUtils.checkNotNull;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "public class Snippet {\n" +
+ " @SuppressWarnings(\"unused\")\n" +
+ " public void foo() {\n" +
+ " @NonNull Object @Nullable [] objects = new @NonNull Object[0];\n" +
+ " @NonNull Object @NonNull [] checked3 = checkNotNull(objects); \n" +
+ " }\n" +
+ "}\n");
+
+ fullBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : Null type mismatch (type annotations): required \'@NonNull Object @NonNull[]\' but this expression has type \'@Nullable Object @NonNull[]\' [" +
+ " resource : range : <321,342> category : <90> severity : <2>]\n" +
+ "Problem : Null type mismatch (type annotations): required \'@Nullable Object @Nullable[]\' but this expression has type \'@NonNull Object @Nullable[]\' [" +
+ " resource : range : <334,341> category : <90> severity : <2>]");
+
+ // fix error according to https://bugs.eclipse.org/bugs/show_bug.cgi?id=481276#c4
+ env.addClass(root, "testNullAnnotations", "NonNullUtils",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "\n" +
+ "public final class NonNullUtils {\n" +
+ "\n" +
+ " public static T[] checkNotNull(T @Nullable[] array) {\n" +
+ " if (array == null) {\n" +
+ " throw new NullPointerException();\n" +
+ " }\n" +
+ " return array;\n" +
+ " }\n" +
+ "}\n");
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testBug481276c() throws Exception {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ setupProjectForNullAnnotations();
+
+ // clean status from https://bugs.eclipse.org/bugs/attachment.cgi?id=257687
+ env.addClass(root, "testNullAnnotations", "package-info",
+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+ "package testNullAnnotations;\n");
+ env.addClass(root, "testNullAnnotations", "NonNullUtils",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "\n" +
+ "public final class NonNullUtils {\n" +
+ "\n" +
+ " public static T[] checkNotNull(T @Nullable [] array) {\n" +
+ " if (array == null) {\n" +
+ " throw new NullPointerException();\n" +
+ " }\n" +
+ " return array;\n" +
+ " }\n" +
+ "}\n");
+ env.addClass(root, "testNullAnnotations", "Snippet",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import static testNullAnnotations.NonNullUtils.checkNotNull;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "public class Snippet {\n" +
+ " @SuppressWarnings(\"unused\")\n" +
+ " public void foo() {\n" +
+ " @NonNull Object @Nullable [] objects = null;\n" +
+ " @NonNull Object @NonNull [] checked3 = checkNotNull(objects); \n" +
+ " }\n" +
+ "}\n");
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ // add a warning by making @NNBD ineffective:
+ env.addClass(root, "testNullAnnotations", "package-info",
+ "@org.eclipse.jdt.annotation.NonNullByDefault({})\n" +
+ "package testNullAnnotations;\n");
+
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ projectPath,
+ "Problem : Null type safety (type annotations): The expression of type \'@NonNull Object []\' needs unchecked conversion to conform to \'@NonNull Object @NonNull[]\' [" +
+ " resource : range : <303,324> category : <90> severity : <1>]");
+ }
+
+ public void testBug483744_remove() throws JavaModelException, IOException {
+ IPath projectPath = env.addProject("Project", "1.8");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+
+ env.removePackageFragmentRoot(projectPath, "");
+
+ IPath root = env.addPackageFragmentRoot(projectPath, "src");
+ env.setOutputFolder(projectPath, "bin");
+
+ setupProjectForNullAnnotations();
+
+ env.addClass(root, "testNullAnnotations", "package-info",
+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+ "package testNullAnnotations;\n");
+ env.addClass(root, "testNullAnnotations", "NonNullUtils",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import java.util.*;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "public final class NonNullUtils {\n" +
+ "\n" +
+ " public static List<@NonNull T> checkNotNullContents(List<@Nullable T> list, List<@NonNull T> nList) {\n" +
+ " return nList;\n" +
+ " }\n" +
+ "}\n");
+ env.addClass(root, "testNullAnnotations", "Snippet",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import java.util.*;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "import static testNullAnnotations.NonNullUtils.checkNotNullContents;\n" +
+ "\n" +
+ "public class Snippet {\n" +
+ " public List<@NonNull String> foo(List<@Nullable String> inList, List<@NonNull String> nList) {\n" +
+ " return checkNotNullContents(inList, nList); \n" +
+ " }\n" +
+ "}\n");
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ // remove @Nullable (second type annotation):
+ env.addClass(root, "testNullAnnotations", "NonNullUtils",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import java.util.*;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "public final class NonNullUtils {\n" +
+ "\n" +
+ " public static List<@NonNull T> checkNotNullContents(List list, List<@NonNull T> nList) {\n" +
+ " return nList;\n" +
+ " }\n" +
+ "}\n");
+ incrementalBuild(projectPath); // was throwing NPE
+ expectingNoProblems();
+
+ // and add it again:
+ env.addClass(root, "testNullAnnotations", "NonNullUtils",
+ "package testNullAnnotations;\n" +
+ "\n" +
+ "import java.util.*;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "public final class NonNullUtils {\n" +
+ "\n" +
+ " public static List<@NonNull T> checkNotNullContents(List<@Nullable T> list, List<@NonNull T> nList) {\n" +
+ " return nList;\n" +
+ " }\n" +
+ "}\n");
+ incrementalBuild(projectPath); // was throwing NPE
+ expectingNoProblems();
+ }
+}
diff --git a/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Java50Tests.java b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Java50Tests.java
new file mode 100644
index 0000000000..c5fc66ebc2
--- /dev/null
+++ b/jdt-patch/e411/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Java50Tests.java
@@ -0,0 +1,382 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import junit.framework.Test;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.tests.util.Util;
+
+public class Java50Tests extends BuilderTests {
+
+ public Java50Tests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(Java50Tests.class);
+ }
+
+ public void testAnnotation() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.5");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "");
+
+ IPath usePath = env.addClass(projectPath, "p", "Use",
+ "package p;\n" +
+ "@q.Ann\n" +
+ "public class Use {\n" +
+ "}"
+ );
+ env.addClass(projectPath, "q", "Ann",
+ "package q;\n" +
+ "public @interface Ann {\n" +
+ "}"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(projectPath, "q", "Ann",
+ "package q;\n" +
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.METHOD)\n" +
+ "public @interface Ann {\n" +
+ "}"
+ );
+
+ incrementalBuild(projectPath);
+ expectingProblemsFor(
+ usePath,
+ "Problem : The annotation @Ann is disallowed for this location [ resource : range : <11,17> category : <40> severity : <2>]"
+ );
+ }
+
+ public void testHierarchyCycle() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.5");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "");
+
+ env.addClass(projectPath, "", "A",
+ "interface A {}\n" +
+ "interface B extends A {}\n" +
+ "interface D extends C {}"
+ );
+ env.addClass(projectPath, "", "C",
+ "interface C extends B {}"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=214237, dupe of
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=205235
+ public void testHierarchyCycleInstanceof() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.5");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "");
+
+ env.addClass(projectPath, "", "A",
+ "import java.util.Collection;\n" +
+ "public abstract class A\n" +
+ ",S extends Collection> {}\n" +
+ // a specific grouping of classes is needed to hit the problem using
+ // the test framework
+ "abstract class B extends A> {\n" +
+ " boolean isD() {return this instanceof D;}\n" +
+ "}\n"+
+ "final class D extends C {}\n"
+ );
+ env.addClass(projectPath, "", "C",
+ "public abstract class C extends B {\n" +
+ " boolean isD() {return this instanceof D;}\n" +
+ "}\n"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=231293
+ public void testMissingRequiredBinaries() throws JavaModelException {
+
+ IPath p1 = env.addProject("P1", "1.5"); //$NON-NLS-1$
+ IPath p2 = env.addProject("P2"); //$NON-NLS-1$
+
+ env.addExternalJars(p1, Util.getJavaClassLibs());
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(p1, ""); //$NON-NLS-1$
+ IPath root1 = env.addPackageFragmentRoot(p1, "src"); //$NON-NLS-1$
+ env.setOutputFolder(p1, "bin"); //$NON-NLS-1$
+
+ env.addExternalJars(p2, Util.getJavaClassLibs());
+ // remove old package fragment root so that names don't collide
+ env.removePackageFragmentRoot(p2, ""); //$NON-NLS-1$
+ IPath root2 = env.addPackageFragmentRoot(p2, "src"); //$NON-NLS-1$
+ IPath p2bin = env.setOutputFolder(p2, "bin"); //$NON-NLS-1$
+
+ env.addClass(root2, "p2", "Y", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p2;\n"+ //$NON-NLS-1$
+ "public class Y {\n"+ //$NON-NLS-1$
+ " public void foo(int i) {}\n"+ //$NON-NLS-1$
+ " public void foo(int i, Z z) {}\n"+ //$NON-NLS-1$
+ "}\n"+ //$NON-NLS-1$
+ "class Z {}" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingNoProblems();
+
+ env.addClassFolder(p1, p2bin, false);
+ env.removeFile(p2bin.append("p2/Z.class")); //$NON-NLS-1$
+
+ env.addClass(root1, "p1", "X", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class X {\n"+ //$NON-NLS-1$
+ " void test(p2.Y y) { y.foo(1); }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(p1);
+ expectingNoProblems();
+
+ IPath xx = env.addClass(root1, "p1", "XX", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p1;\n"+ //$NON-NLS-1$
+ "public class XX {\n"+ //$NON-NLS-1$
+ " void test(p2.Y y) { y.foo('c', null); }\n"+ //$NON-NLS-1$
+ "}\n" //$NON-NLS-1$
+ );
+
+ incrementalBuild(p1);
+ expectingOnlySpecificProblemsFor(p1,new Problem[]{
+ new Problem("p1", "The project was not built since its build path is incomplete. Cannot find the class file for p2.Z. Fix the build path then try building this project", p1, -1, -1, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR),//$NON-NLS-1$ //$NON-NLS-2$
+ new Problem("p1", "The type p2.Z cannot be resolved. It is indirectly referenced from required .class files", xx, 51, 67, CategorizedProblem.CAT_BUILDPATH, IMarker.SEVERITY_ERROR)//$NON-NLS-1$ //$NON-NLS-2$
+ });
+ }
+
+ public void testParameterizedMemberType() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.5");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "");
+
+ IPath xPath = env.addClass(projectPath, "", "X",
+ "class X extends A {}"
+ );
+
+ IPath aPath = env.addClass(projectPath, "", "A",
+ "class A extends B.M> {}"
+ );
+
+ IPath bPath = env.addClass(projectPath, "", "B",
+ "class B extends Missing {\n" +
+ " class M{}\n" +
+ "}\n" +
+ "class Missing {}"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(projectPath, "", "B",
+ "class B extends Missing {\n" +
+ " class M{}\n" +
+ "}"
+ );
+
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(xPath, new Problem("X", "The hierarchy of the type X is inconsistent", xPath, 6, 7, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(aPath, new Problem("A", "The hierarchy of the type A is inconsistent", aPath, 6, 7, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(bPath, new Problem("B", "Missing cannot be resolved to a type", bPath, 19, 26, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(projectPath, "", "X",
+ "class X extends A {}"
+ );
+
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(xPath, new Problem("X", "The hierarchy of the type X is inconsistent", xPath, 6, 7, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(aPath, new Problem("A", "The hierarchy of the type A is inconsistent", aPath, 6, 7, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(bPath, new Problem("B", "Missing cannot be resolved to a type", bPath, 19, 26, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(projectPath, "", "B",
+ "class B extends Missing {\n" +
+ " class M{}\n" +
+ "}"
+ );
+
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(xPath, new Problem("X", "The hierarchy of the type X is inconsistent", xPath, 6, 7, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(aPath, new Problem("A", "The hierarchy of the type A is inconsistent", aPath, 6, 7, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(bPath, new Problem("B", "Missing cannot be resolved to a type", bPath, 19, 26, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ env.addClass(projectPath, "", "B",
+ "class B extends Missing {\n" +
+ " class M{}\n" +
+ "}\n" +
+ "class Missing {}"
+ );
+
+ incrementalBuild(projectPath);
+ expectingNoProblems();
+ }
+
+ public void testParameterizedType1() throws JavaModelException {
+ IPath projectPath = env.addProject("Project", "1.5");
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "");
+
+ IPath usePath = env.addClass(projectPath, "p", "Use",
+ "package p;\n" +
+ "import java.util.ArrayList;\n" +
+ "import q.Other;\n" +
+ "public class Use {\n" +
+ " public Use() {\n" +
+ " new Other().foo(new ArrayList());\n" +
+ " }\n" +
+ "}"
+ );
+ env.addClass(projectPath, "q", "Other",
+ "package q;\n" +
+ "import java.util.List;\n" +
+ "public class Other {\n" +
+ " public void foo(List ls) {}\n" +
+ "}"
+ );
+
+ fullBuild(projectPath);
+ expectingNoProblems();
+
+ env.addClass(projectPath, "q", "Other",
+ "package q;\n" +
+ "import java.util.List;\n" +
+ "public class Other {\n" +
+ " public void foo(List