Merge remote-tracking branch 'origin/master' into BETA_JAVA_12
# Conflicts:
# org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java
Change-Id: I406b6d7693cc43faf7f2365f39514b2173b92ca3
diff --git a/CONTRIBUTING b/CONTRIBUTING
new file mode 100644
index 0000000..137f076
--- /dev/null
+++ b/CONTRIBUTING
@@ -0,0 +1,59 @@
+# Contributing to Eclipse Java development tools
+
+Thanks for your interest in this project.
+
+## Project description
+
+The JDT project provides the tool plug-ins that implement a Java IDE supporting
+the development of any Java application, including Eclipse plug-ins. It adds a
+Java project nature and Java perspective to the Eclipse Workbench as well as a
+number of views, editors, wizards, builders, and code merging and refactoring
+tools. The JDT project allows Eclipse to be a development environment for
+itself.
+
+* https://projects.eclipse.org/projects/eclipse.jdt
+
+## Developer resources
+
+Information regarding source code management, builds, coding standards, and
+more.
+
+* https://projects.eclipse.org/projects/eclipse.jdt/developer
+
+The project maintains the following source code repositories
+
+* http://git.eclipse.org/c/jdt/eclipse.jdt.core.binaries.git
+* http://git.eclipse.org/c/jdt/eclipse.jdt.core.git
+* http://git.eclipse.org/c/jdt/eclipse.jdt.debug.git
+* http://git.eclipse.org/c/jdt/eclipse.jdt.git
+* http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git
+
+This project uses Bugzilla to track ongoing development and issues.
+
+* Search for issues: https://eclipse.org/bugs/buglist.cgi?product=JDT
+* Create a new report: https://eclipse.org/bugs/enter_bug.cgi?product=JDT
+
+Be sure to search for existing bugs before you create another one. Remember that
+contributions are always welcome!
+
+## Eclipse Contributor Agreement
+
+Before your contribution can be accepted by the project team contributors must
+electronically sign the Eclipse Contributor Agreement (ECA).
+
+* http://www.eclipse.org/legal/ECA.php
+
+Commits that are provided by non-committers must have a Signed-off-by field in
+the footer indicating that the author is aware of the terms by which the
+contribution has been provided to the project. The non-committer must
+additionally have an Eclipse Foundation account and must have a signed Eclipse
+Contributor Agreement (ECA) on file.
+
+For more information, please see the Eclipse Committer Handbook:
+https://www.eclipse.org/projects/handbook/#resources-commit
+
+## Contact
+
+Contact the project developers via the project's "dev" list.
+
+* https://dev.eclipse.org/mailman/listinfo/jdt-dev
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e23ece2
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,277 @@
+Eclipse Public License - v 2.0
+
+ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+ PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION
+ OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+ a) in the case of the initial Contributor, the initial content
+ Distributed under this Agreement, and
+
+ b) in the case of each subsequent Contributor:
+ i) changes to the Program, and
+ ii) additions to the Program;
+ where such changes and/or additions to the Program originate from
+ and are Distributed by that particular Contributor. A Contribution
+ "originates" from a Contributor if it was added to the Program by
+ such Contributor itself or anyone acting on such Contributor's behalf.
+ Contributions do not include changes or additions to the Program that
+ are not Modified Works.
+
+"Contributor" means any person or entity that Distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which
+are necessarily infringed by the use or sale of its Contribution alone
+or when combined with the Program.
+
+"Program" means the Contributions Distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement
+or any Secondary License (as applicable), including Contributors.
+
+"Derivative Works" shall mean any work, whether in Source Code or other
+form, that is based on (or derived from) the Program and for which the
+editorial revisions, annotations, elaborations, or other modifications
+represent, as a whole, an original work of authorship.
+
+"Modified Works" shall mean any work in Source Code or other form that
+results from an addition to, deletion from, or modification of the
+contents of the Program, including, for purposes of clarity any new file
+in Source Code form that contains any contents of the Program. Modified
+Works shall not include works that contain only declarations,
+interfaces, types, classes, structures, or files of the Program solely
+in each case in order to link to, bind by name, or subclass the Program
+or Modified Works thereof.
+
+"Distribute" means the acts of a) distributing or b) making available
+in any manner that enables the transfer of a copy.
+
+"Source Code" means the form of a Program preferred for making
+modifications, including but not limited to software source code,
+documentation source, and configuration files.
+
+"Secondary License" means either the GNU General Public License,
+Version 2.0, or any later versions of that license, including any
+exceptions or additional permissions as identified by the initial
+Contributor.
+
+2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each Contributor hereby
+ grants Recipient a non-exclusive, worldwide, royalty-free copyright
+ license to reproduce, prepare Derivative Works of, publicly display,
+ publicly perform, Distribute and sublicense the Contribution of such
+ Contributor, if any, and such Derivative Works.
+
+ b) Subject to the terms of this Agreement, each Contributor hereby
+ grants Recipient a non-exclusive, worldwide, royalty-free patent
+ license under Licensed Patents to make, use, sell, offer to sell,
+ import and otherwise transfer the Contribution of such Contributor,
+ if any, in Source Code or other form. This patent license shall
+ apply to the combination of the Contribution and the Program if, at
+ the time the Contribution is added by the Contributor, such addition
+ of the Contribution causes such combination to be covered by the
+ Licensed Patents. The patent license shall not apply to any other
+ combinations which include the Contribution. No hardware per se is
+ licensed hereunder.
+
+ c) Recipient understands that although each Contributor grants the
+ licenses to its Contributions set forth herein, no assurances are
+ provided by any Contributor that the Program does not infringe the
+ patent or other intellectual property rights of any other entity.
+ Each Contributor disclaims any liability to Recipient for claims
+ brought by any other entity based on infringement of intellectual
+ property rights or otherwise. As a condition to exercising the
+ rights and licenses granted hereunder, each Recipient hereby
+ assumes sole responsibility to secure any other intellectual
+ property rights needed, if any. For example, if a third party
+ patent license is required to allow Recipient to Distribute the
+ Program, it is Recipient's responsibility to acquire that license
+ before distributing the Program.
+
+ d) Each Contributor represents that to its knowledge it has
+ sufficient copyright rights in its Contribution, if any, to grant
+ the copyright license set forth in this Agreement.
+
+ e) Notwithstanding the terms of any Secondary License, no
+ Contributor makes additional grants to any Recipient (other than
+ those set forth in this Agreement) as a result of such Recipient's
+ receipt of the Program under the terms of a Secondary License
+ (if permitted under the terms of Section 3).
+
+3. REQUIREMENTS
+
+3.1 If a Contributor Distributes the Program in any form, then:
+
+ a) the Program must also be made available as Source Code, in
+ accordance with section 3.2, and the Contributor must accompany
+ the Program with a statement that the Source Code for the Program
+ is available under this Agreement, and informs Recipients how to
+ obtain it in a reasonable manner on or through a medium customarily
+ used for software exchange; and
+
+ b) the Contributor may Distribute the Program under a license
+ different than this Agreement, provided that such license:
+ i) effectively disclaims on behalf of all other Contributors all
+ warranties and conditions, express and implied, including
+ warranties or conditions of title and non-infringement, and
+ implied warranties or conditions of merchantability and fitness
+ for a particular purpose;
+
+ ii) effectively excludes on behalf of all other Contributors all
+ liability for damages, including direct, indirect, special,
+ incidental and consequential damages, such as lost profits;
+
+ iii) does not attempt to limit or alter the recipients' rights
+ in the Source Code under section 3.2; and
+
+ iv) requires any subsequent distribution of the Program by any
+ party to be under a license that satisfies the requirements
+ of this section 3.
+
+3.2 When the Program is Distributed as Source Code:
+
+ a) it must be made available under this Agreement, or if the
+ Program (i) is combined with other material in a separate file or
+ files made available under a Secondary License, and (ii) the initial
+ Contributor attached to the Source Code the notice described in
+ Exhibit A of this Agreement, then the Program may be made available
+ under the terms of such Secondary Licenses, and
+
+ b) a copy of this Agreement must be included with each copy of
+ the Program.
+
+3.3 Contributors may not remove or alter any copyright, patent,
+trademark, attribution notices, disclaimers of warranty, or limitations
+of liability ("notices") contained within the Program from any copy of
+the Program which they Distribute, provided that Contributors may add
+their own appropriate notices.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities
+with respect to end users, business partners and the like. While this
+license is intended to facilitate the commercial use of the Program,
+the Contributor who includes the Program in a commercial product
+offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes
+the Program in a commercial product offering, such Contributor
+("Commercial Contributor") hereby agrees to defend and indemnify every
+other Contributor ("Indemnified Contributor") against any losses,
+damages and costs (collectively "Losses") arising from claims, lawsuits
+and other legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such
+Commercial Contributor in connection with its distribution of the Program
+in a commercial product offering. The obligations in this section do not
+apply to any claims or Losses relating to any actual or alleged
+intellectual property infringement. In order to qualify, an Indemnified
+Contributor must: a) promptly notify the Commercial Contributor in
+writing of such claim, and b) allow the Commercial Contributor to control,
+and cooperate with the Commercial Contributor in, the defense and any
+related settlement negotiations. The Indemnified Contributor may
+participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those performance
+claims and warranties, and if a court requires any other Contributor to
+pay any damages as a result, the Commercial Contributor must pay
+those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS"
+BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF
+TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+PURPOSE. Each Recipient is solely responsible for determining the
+appropriateness of using and distributing the Program and assumes all
+risks associated with its exercise of rights under this Agreement,
+including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs
+or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS
+SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further
+action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other software
+or hardware) infringes such Recipient's patent(s), then such Recipient's
+rights granted under Section 2(b) shall terminate as of the date such
+litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of
+time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use
+and distribution of the Program as soon as reasonably practicable.
+However, Recipient's obligations under this Agreement and any licenses
+granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and
+may only be modified in the following manner. The Agreement Steward
+reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement
+Steward has the right to modify this Agreement. The Eclipse Foundation
+is the initial Agreement Steward. The Eclipse Foundation may assign the
+responsibility to serve as the Agreement Steward to a suitable separate
+entity. Each new version of the Agreement will be given a distinguishing
+version number. The Program (including Contributions) may always be
+Distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is published,
+Contributor may elect to Distribute the Program (including its
+Contributions) under the new version.
+
+Except as expressly stated in Sections 2(a) and 2(b) above, Recipient
+receives no rights or licenses to the intellectual property of any
+Contributor under this Agreement, whether expressly, by implication,
+estoppel or otherwise. All rights in the Program not expressly granted
+under this Agreement are reserved. Nothing in this Agreement is intended
+to be enforceable by any entity that is not a Contributor or Recipient.
+No third-party beneficiary rights are created under this Agreement.
+
+Exhibit A - Form of Secondary Licenses Notice
+
+"This Source Code may also be made available under the following
+Secondary Licenses when the conditions for such availability set forth
+in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),
+version(s), and exceptions or additional permissions here}."
+
+ Simply including a copy of this Agreement, including this Exhibit A
+ is not sufficient to license the Source Code under Secondary Licenses.
+
+ If it is not possible or desirable to put the notice in a particular
+ file, then You may include the notice in a location (such as a LICENSE
+ file in a relevant directory) where a recipient would be likely to
+ look for such a notice.
+
+ You may add additional accurate notices of copyright ownership.
\ No newline at end of file
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..62de25b
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,35 @@
+# Notices for Eclipse Java development tools
+
+This content is produced and maintained by the Eclipse Java development tools
+project.
+
+* Project home: https://projects.eclipse.org/projects/eclipse.jdt
+
+## Trademarks
+
+Eclipse Java development tools, Java development tools, Eclipse JDT, and JDT are
+trademarks of the Eclipse Foundation.
+
+## Copyright
+
+All content is the property of the respective authors or their employers. For
+more information regarding authorship of content, please consult the listed
+source code repository logs.
+
+## Declared Project Licenses
+
+This program and the accompanying materials are made available under the terms
+of the Eclipse Public License v. 2.0 which is available at
+http://www.eclipse.org/legal/epl-2.0.
+
+SPDX-License-Identifier: EPL-2.0
+
+## Source Code
+
+The project maintains the following source code repositories:
+
+* http://git.eclipse.org/c/jdt/eclipse.jdt.core.binaries.git
+* http://git.eclipse.org/c/jdt/eclipse.jdt.core.git
+* http://git.eclipse.org/c/jdt/eclipse.jdt.debug.git
+* http://git.eclipse.org/c/jdt/eclipse.jdt.git
+* http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolJava9Tests.java b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolJava9Tests.java
index dcb6b28..83133f1 100644
--- a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolJava9Tests.java
+++ b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolJava9Tests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2017 IBM Corporation and others.
+ * Copyright (c) 2017, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -725,10 +725,6 @@
super.report(diagnostic);
}
- public int getErrorCount() {
- return errorList.size();
- }
-
public boolean hasDiagnostic(String match) {
for(Diagnostic<? extends JavaFileObject> d: errorList) {
String msg = d.getMessage(Locale.US).toLowerCase();
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
index d1f50ca..15771d9 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
@@ -94,7 +94,7 @@
performCompilation();
}
} catch(IllegalArgumentException e) {
- diagnosticListener.report(new ExceptionDiagnostic(e));
+ this.diagnosticListener.report(new ExceptionDiagnostic(e));
this.logger.logException(e);
if (this.systemExitWhenFinished) {
cleanup();
@@ -102,7 +102,7 @@
}
return false;
} catch (RuntimeException e) { // internal compiler failure
- diagnosticListener.report(new ExceptionDiagnostic(e));
+ this.diagnosticListener.report(new ExceptionDiagnostic(e));
e.printStackTrace();
this.logger.logException(e);
return false;
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/ExceptionDiagnostic.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/ExceptionDiagnostic.java
index 8822b36..5afe834 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/ExceptionDiagnostic.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/ExceptionDiagnostic.java
@@ -17,7 +17,6 @@
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
-import javax.tools.Diagnostic.Kind;
final class ExceptionDiagnostic implements Diagnostic<JavaFileObject> {
private final Exception exception;
@@ -28,7 +27,7 @@
@Override
public String getCode() {
- return "exception";
+ return "exception"; //$NON-NLS-1$
}
@Override
@@ -53,7 +52,7 @@
@Override
public String getMessage(Locale arg0) {
- return exception.toString();
+ return this.exception.toString();
}
@Override
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index 426340e..6bba0e9 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -248,6 +248,10 @@
StringBuffer classpathBuffer = new StringBuffer(" -classpath ");
this.classpath = classpathBuffer.toString();
}
+ /** Call this if " -classpath " should be replaced by some other option token. */
+ protected void usePathOption(String option) {
+ this.classpath = option;
+ }
static String getVersion(String javacPathName) throws IOException, InterruptedException {
Process fetchVersionProcess = null;
try {
@@ -1028,7 +1032,7 @@
// list of available javac compilers, as defined by the jdk.roots
// variable, which should hold a File.pathSeparatorChar separated
// list of paths for to-be-tested JDK root directories
- protected static List javacCompilers = null;
+ protected static List<JavacCompiler> javacCompilers = null;
public static final String OUTPUT_DIR = Util.getOutputDirectory() + File.separator + "regression";
public static final String LIB_DIR = Util.getOutputDirectory() + File.separator + "lib";
@@ -1881,7 +1885,15 @@
expectedSuccessOutputString,
null,
javacTestOptions);
+ }
+
+ protected static void javacUsePathOption(String option) {
+ if (AbstractRegressionTest.javacCompilers != null) {
+ for (JavacCompiler compiler : AbstractRegressionTest.javacCompilers) {
+ compiler.usePathOption(option);
+ }
}
+ }
/*
* Run Sun compilation using javac.
@@ -2196,9 +2208,9 @@
}
}
String testName = testName();
- Iterator compilers = javacCompilers.iterator();
+ Iterator<JavacCompiler> compilers = javacCompilers.iterator();
while (compilers.hasNext()) {
- JavacCompiler compiler = (JavacCompiler) compilers.next();
+ JavacCompiler compiler = compilers.next();
if (!options.skip(compiler) && compiler.compliance == this.complianceLevel) {
// WORK this may exclude some compilers under some conditions (when
// complianceLevel is not set); consider accepting the compiler
@@ -2220,6 +2232,7 @@
for (int i = 0, length = testFiles.length; i < length; ) {
String fileName = testFiles[i++];
String contents = testFiles[i++];
+ fileName = expandFileNameForJavac(fileName);
File file = new File(javacOutputDirectory, fileName);
if (fileName.lastIndexOf('/') >= 0) {
File dir = file.getParentFile();
@@ -2233,7 +2246,7 @@
int testFilesLength = testFiles.length;
sourceFileNames = new String[testFilesLength / 2];
for (int i = 0, j = 0; i < testFilesLength; i += 2, j++) {
- sourceFileNames[j] = testFiles[i];
+ sourceFileNames[j] = expandFileNameForJavac(testFiles[i]);
}
// compile
@@ -2336,6 +2349,10 @@
}
}
}
+/** Hook for AbstractRegressionTest9 */
+protected String expandFileNameForJavac(String fileName) {
+ return fileName;
+}
void handleMismatch(JavacCompiler compiler, String testName, String[] testFiles, String expectedCompilerLog,
String expectedOutputString, String expectedErrorString, StringBuffer compilerLog, String output, String err,
JavacTestOptions.Excuse excuse, int mismatch) {
@@ -3585,7 +3602,7 @@
System.out.println("* Sun Javac compiler output archived into file:");
System.out.println("* " + javacFullLogFileName);
System.out.println("***************************************************************************");
- javacCompilers = new ArrayList();
+ javacCompilers = new ArrayList<>();
String jdkRoots = System.getProperty("jdk.roots");
if (jdkRoots == null) {
javacCompilers.add(new JavacCompiler(jdkRootDirPath.toString()));
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest9.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest9.java
index cc49625..57db3e4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest9.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest9.java
@@ -89,6 +89,18 @@
return compilationUnits;
}
+ /**
+ * javac cannot leverage our internal map {@code file2module}, so we better
+ * neatly place each file into a sub directory matching the module name.
+ */
+ protected String expandFileNameForJavac(String fileName) {
+ String fileNameAsKey = fileName.replace(File.separator, "/");
+ if (this.file2module != null && this.file2module.containsKey(fileNameAsKey)) {
+ fileName = new String(this.file2module.get(fileNameAsKey))+File.separator+fileName;
+ }
+ return fileName;
+ }
+
private IModule extractModuleDesc(String fileName, String fileContent, ICompilationUnit cu) {
if (fileName.toLowerCase().endsWith(IModule.MODULE_INFO_JAVA)) {
Parser parser = createParser();
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java
index f5828ae..6f12b7d 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java
@@ -688,7 +688,8 @@
runner.runNegativeTest();
}
public void testDeprecatedProvidedServices() {
- associateToModule("mod0", "p1/IServiceDep.java", "p1/IServiceDepSince.java", "p1/IServiceTermDep.java", "p1/IServiceTermDepSince.java");
+ javacUsePathOption(" --module-source-path ");
+ associateToModule("mod0", "module-info.java", "p1/IServiceDep.java", "p1/IServiceDepSince.java", "p1/IServiceTermDep.java", "p1/IServiceTermDepSince.java");
associateToModule("mod1", "p1impl/ServiceDep.java", "p1impl/ServiceDepSince.java", "p1impl/ServiceTermDep.java", "p1impl/ServiceTermDepSince.java");
Runner runner = new Runner();
runner.customOptions = new HashMap<>();
@@ -732,7 +733,7 @@
"package p1impl;\n" +
"@Deprecated(since=\"3\",forRemoval=true)\n" +
"public class ServiceTermDepSince implements p1.IServiceTermDepSince {}\n",
- "folder2/module-info.java",
+ "mod1/module-info.java",
"module mod1 {\n" +
" requires mod0;\n" +
" provides p1.IServiceDep with p1impl.ServiceDep;\n" +
@@ -743,42 +744,42 @@
};
runner.expectedCompilerLog =
"----------\n" +
- "1. INFO in folder2\\module-info.java (at line 3)\n" +
+ "1. INFO in mod1\\module-info.java (at line 3)\n" +
" provides p1.IServiceDep with p1impl.ServiceDep;\n" +
" ^^^^^^^^^^^\n" +
"The type IServiceDep is deprecated\n" +
"----------\n" +
- "2. INFO in folder2\\module-info.java (at line 3)\n" +
+ "2. INFO in mod1\\module-info.java (at line 3)\n" +
" provides p1.IServiceDep with p1impl.ServiceDep;\n" +
" ^^^^^^^^^^\n" +
"The type ServiceDep is deprecated\n" +
"----------\n" +
- "3. INFO in folder2\\module-info.java (at line 4)\n" +
+ "3. INFO in mod1\\module-info.java (at line 4)\n" +
" provides p1.IServiceDepSince with p1impl.ServiceDepSince;\n" +
" ^^^^^^^^^^^^^^^^\n" +
"The type IServiceDepSince is deprecated since version 2\n" +
"----------\n" +
- "4. INFO in folder2\\module-info.java (at line 4)\n" +
+ "4. INFO in mod1\\module-info.java (at line 4)\n" +
" provides p1.IServiceDepSince with p1impl.ServiceDepSince;\n" +
" ^^^^^^^^^^^^^^^\n" +
"The type ServiceDepSince is deprecated since version 2\n" +
"----------\n" +
- "5. WARNING in folder2\\module-info.java (at line 5)\n" +
+ "5. WARNING in mod1\\module-info.java (at line 5)\n" +
" provides p1.IServiceTermDep with p1impl.ServiceTermDep;\n" +
" ^^^^^^^^^^^^^^^\n" +
"The type IServiceTermDep has been deprecated and marked for removal\n" +
"----------\n" +
- "6. WARNING in folder2\\module-info.java (at line 5)\n" +
+ "6. WARNING in mod1\\module-info.java (at line 5)\n" +
" provides p1.IServiceTermDep with p1impl.ServiceTermDep;\n" +
" ^^^^^^^^^^^^^^\n" +
"The type ServiceTermDep has been deprecated and marked for removal\n" +
"----------\n" +
- "7. WARNING in folder2\\module-info.java (at line 6)\n" +
+ "7. WARNING in mod1\\module-info.java (at line 6)\n" +
" provides p1.IServiceTermDepSince with p1impl.ServiceTermDepSince;\n" +
" ^^^^^^^^^^^^^^^^^^^^\n" +
"The type IServiceTermDepSince has been deprecated since version 3 and marked for removal\n" +
"----------\n" +
- "8. WARNING in folder2\\module-info.java (at line 6)\n" +
+ "8. WARNING in mod1\\module-info.java (at line 6)\n" +
" provides p1.IServiceTermDepSince with p1impl.ServiceTermDepSince;\n" +
" ^^^^^^^^^^^^^^^^^^^\n" +
"The type ServiceTermDepSince has been deprecated since version 3 and marked for removal\n" +
@@ -786,6 +787,8 @@
runner.runWarningTest();
}
public void testDeprecatedUsedServices() {
+ javacUsePathOption(" --module-path ");
+
associateToModule("mod0", "p1/IServiceDep.java", "p1/IServiceDepSince.java", "p1/IServiceTermDep.java", "p1/IServiceTermDepSince.java");
Runner runner = new Runner();
runner.customOptions = new HashMap<>();
@@ -864,18 +867,54 @@
" requires jdk.xml.bind;\n" +
"}\n"
};
- runner.expectedCompilerLog =
- "----------\n" +
- "1. WARNING in module-info.java (at line 2)\n" +
- " requires jdk.xml.bind;\n" +
- " ^^^^^^^^^^^^\n" +
- "The module jdk.xml.bind has been deprecated since version 9 and marked for removal\n" +
- "----------\n";
- runner.runWarningTest();
+ if (isJRE11Plus) {
+ runner.expectedCompilerLog =
+ "----------\n" +
+ "1. ERROR in module-info.java (at line 2)\n" +
+ " requires jdk.xml.bind;\n" +
+ " ^^^^^^^^^^^^\n" +
+ "jdk.xml.bind cannot be resolved to a module\n" +
+ "----------\n";
+ runner.runNegativeTest();
+ } else {
+ runner.expectedCompilerLog =
+ "----------\n" +
+ "1. WARNING in module-info.java (at line 2)\n" +
+ " requires jdk.xml.bind;\n" +
+ " ^^^^^^^^^^^^\n" +
+ "The module jdk.xml.bind has been deprecated since version 9 and marked for removal\n" +
+ "----------\n";
+ runner.runWarningTest();
+ }
} finally {
this.javaClassLib = save;
}
}
+ public void testBug533063_2() throws Exception {
+ javacUsePathOption(" --module-path ");
+
+ runConformTest(new String[] {
+ "dont.use/module-info.java",
+ "@Deprecated(forRemoval=true,since=\"9\") module dont.use {}\n"
+ });
+ this.moduleMap.clear(); // don't use the source module beyond this point
+ Runner runner = new Runner();
+ runner.shouldFlushOutputDirectory = false;
+ runner.testFiles = new String[] {
+ "my.mod/module-info.java",
+ "module my.mod {\n" +
+ " requires dont.use;\n" +
+ "}\n"
+ };
+ runner.expectedCompilerLog =
+ "----------\n" +
+ "1. WARNING in my.mod\\module-info.java (at line 2)\n" +
+ " requires dont.use;\n" +
+ " ^^^^^^^^\n" +
+ "The module dont.use has been deprecated since version 9 and marked for removal\n" +
+ "----------\n";
+ runner.runWarningTest();
+ }
public void testBug534304() throws Exception {
runNegativeTest(
new String[] {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java
index cf2ad8a..5f7992e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java
@@ -897,6 +897,8 @@
" }\n" +
"}\n"
},
+ this.complianceLevel < ClassFileConstants.JDK11
+ ?
"----------\n" +
"1. WARNING in ShowBug.java (at line 9)\n" +
" final X x = new X() {\n" +
@@ -907,6 +909,13 @@
" x.x(val - 1);\n" +
" ^\n" +
"The local variable x may not have been initialized\n" +
+ "----------\n"
+ :
+ "----------\n" +
+ "1. ERROR in ShowBug.java (at line 13)\n" +
+ " x.x(val - 1);\n" +
+ " ^\n" +
+ "The local variable x may not have been initialized\n" +
"----------\n");
}
public static Class testClass() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
index e674649..74b75a5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
@@ -40,7 +40,7 @@
public class ModuleCompilationTests extends AbstractBatchCompilerTest {
static {
-// TESTS_NAMES = new String[] { "test_npe_bug535107" };
+// TESTS_NAMES = new String[] { "testBug540067e" };
// TESTS_NUMBERS = new int[] { 1 };
// TESTS_RANGE = new int[] { 298, -1 };
}
@@ -162,8 +162,7 @@
if (javacCommandLine == null) {
javacCommandLine = adjustForJavac(commandLine, null);
}
- for (Object comp : javacCompilers) {
- JavacCompiler javacCompiler = (JavacCompiler) comp;
+ for (JavacCompiler javacCompiler : javacCompilers) {
if (javacCompiler.compliance < ClassFileConstants.JDK9)
continue;
if (options.skip(javacCompiler)) {
@@ -240,8 +239,7 @@
File outputDir = new File(OUTPUT_DIR);
final Set<String> outFiles = new HashSet<>();
walkOutFiles(output, outFiles, true);
- for (Object comp : javacCompilers) {
- JavacCompiler javacCompiler = (JavacCompiler) comp;
+ for (JavacCompiler javacCompiler : javacCompilers) {
if (javacCompiler.compliance < ClassFileConstants.JDK9)
continue;
JavacTestOptions.Excuse excuse = options.excuseFor(javacCompiler);
@@ -3632,11 +3630,7 @@
" ^^\n" +
"The package p1 does not exist or is empty\n" +
"----------\n" +
- "----------\n" +
- "2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/p1/X.java\n" +
- "Must declare a named package because this compilation unit is associated to the named module \'mod.one\'\n" +
- "----------\n" +
- "2 problems (2 errors)\n",
+ "1 problem (1 error)\n",
false,
"empty",
OUTPUT_DIR + File.separator + out);
@@ -5006,4 +5000,200 @@
"",
true);
}
+ public void testBug540067a() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+ String out = "bin";
+ String directory = OUTPUT_DIR + File.separator + "src";
+ String moduleLoc = directory + File.separator + "mod.one";
+ List<String> files = new ArrayList<>();
+ writeFileCollecting(files, moduleLoc, "module-info.java",
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}");
+ writeFileCollecting(files, moduleLoc + File.separator + "p", "X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ "}");
+ writeFileCollecting(files, moduleLoc + File.separator + "p" + File.separator + "q", "Test.java",
+ "/*nothing in it */");
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("-d " + OUTPUT_DIR + File.separator + out )
+ .append(" -9 ")
+ .append(" -classpath \"")
+ .append(Util.getJavaClassLibsAsString())
+ .append("\" ")
+ .append(" --module-source-path " + "\"" + directory + "\" ")
+ .append(moduleLoc + File.separator + "module-info.java ")
+ .append(moduleLoc + File.separator + "p" + File.separator + "X.java ")
+ .append(moduleLoc + File.separator + "p" + File.separator + "q" + File.separator + "Test.java");
+
+ runConformModuleTest(
+ new String[0],
+ buffer.toString(),
+ "",
+ "",
+ false);
+ }
+ public void testBug540067b() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+ String out = "bin";
+ String directory = OUTPUT_DIR + File.separator + "src";
+ String moduleLoc = directory + File.separator + "mod.one";
+ List<String> files = new ArrayList<>();
+ writeFileCollecting(files, moduleLoc, "module-info.java",
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}");
+ writeFileCollecting(files, moduleLoc + File.separator + "p", "X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ "}");
+ writeFileCollecting(files, moduleLoc + File.separator + "p" + File.separator + "q", "Test.java",
+ "package p.q;");
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("-d " + OUTPUT_DIR + File.separator + out )
+ .append(" -9 ")
+ .append(" -classpath \"")
+ .append(Util.getJavaClassLibsAsString())
+ .append("\" ")
+ .append(" --module-source-path " + "\"" + directory + "\" ")
+ .append(moduleLoc + File.separator + "module-info.java ")
+ .append(moduleLoc + File.separator + "p" + File.separator + "X.java ")
+ .append(moduleLoc + File.separator + "p" + File.separator + "q" + File.separator + "Test.java");
+
+ runConformModuleTest(
+ new String[0],
+ buffer.toString(),
+ "",
+ "",
+ false);
+ }
+ public void testBug540067c() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+ String out = "bin";
+ String directory = OUTPUT_DIR + File.separator + "src";
+ String moduleLoc = directory + File.separator + "mod.one";
+ List<String> files = new ArrayList<>();
+ writeFileCollecting(files, moduleLoc, "module-info.java",
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}");
+ writeFileCollecting(files, moduleLoc + File.separator + "p", "X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ "}");
+ writeFileCollecting(files, moduleLoc + File.separator + "p" + File.separator + "q", "Test.java",
+ "package p.q;\n"
+ + "class Test {}");
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("-d " + OUTPUT_DIR + File.separator + out )
+ .append(" -9 ")
+ .append(" -classpath \"")
+ .append(Util.getJavaClassLibsAsString())
+ .append("\" ")
+ .append(" --module-source-path " + "\"" + directory + "\" ")
+ .append(moduleLoc + File.separator + "module-info.java ")
+ .append(moduleLoc + File.separator + "p" + File.separator + "X.java ")
+ .append(moduleLoc + File.separator + "p" + File.separator + "q" + File.separator + "Test.java");
+
+ runConformModuleTest(
+ new String[0],
+ buffer.toString(),
+ "",
+ "",
+ false);
+ }
+ public void testBug540067d() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+ String out = "bin";
+ String directory = OUTPUT_DIR + File.separator + "src";
+ String moduleLoc = directory + File.separator + "mod.one";
+ List<String> files = new ArrayList<>();
+ writeFileCollecting(files, moduleLoc, "module-info.java",
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}");
+ writeFileCollecting(files, moduleLoc + File.separator + "p", "X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ "}");
+ writeFileCollecting(files, moduleLoc + File.separator + "p" + File.separator + "q", "Test.java",
+ "class Test {}");
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("-d " + OUTPUT_DIR + File.separator + out )
+ .append(" -9 ")
+ .append(" -classpath \"")
+ .append(Util.getJavaClassLibsAsString())
+ .append("\" ")
+ .append(" --module-source-path " + "\"" + directory + "\" ")
+ .append(moduleLoc + File.separator + "module-info.java ")
+ .append(moduleLoc + File.separator + "p" + File.separator + "X.java ")
+ .append(moduleLoc + File.separator + "p" + File.separator + "q" + File.separator + "Test.java");
+
+ runNegativeModuleTest(
+ new String[0],
+ buffer.toString(),
+ "",
+ "----------\n" +
+ "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/p/q/Test.java (at line 1)\n" +
+ " class Test {}\n" +
+ " ^\n" +
+ "Must declare a named package because this compilation unit is associated to the named module \'mod.one\'\n" +
+ "----------\n" +
+ "1 problem (1 error)\n",
+ false,
+ "unnamed package is not allowed in named modules");
+ }
+ public void testBug540067e() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+ String out = "bin";
+ String directory = OUTPUT_DIR + File.separator + "src";
+ String moduleLoc = directory + File.separator + "mod.one";
+ List<String> files = new ArrayList<>();
+ writeFileCollecting(files, moduleLoc, "module-info.java",
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}");
+ writeFileCollecting(files, moduleLoc + File.separator + "p", "X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ "}");
+ writeFileCollecting(files, moduleLoc + File.separator + "p" + File.separator + "q", "Test.java",
+ "import java.lang.*;");
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("-d " + OUTPUT_DIR + File.separator + out )
+ .append(" -9 ")
+ .append(" -classpath \"")
+ .append(Util.getJavaClassLibsAsString())
+ .append("\" ")
+ .append(" -warn:-unused")
+ .append(" --module-source-path " + "\"" + directory + "\" ")
+ .append(moduleLoc + File.separator + "module-info.java ")
+ .append(moduleLoc + File.separator + "p" + File.separator + "X.java ")
+ .append(moduleLoc + File.separator + "p" + File.separator + "q" + File.separator + "Test.java");
+
+ runNegativeModuleTest(
+ new String[0],
+ buffer.toString(),
+ "",
+ "----------\n" +
+ "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/p/q/Test.java (at line 1)\n" +
+ " import java.lang.*;\n" +
+ " ^\n" +
+ "Must declare a named package because this compilation unit is associated to the named module \'mod.one\'\n" +
+ "----------\n" +
+ "1 problem (1 error)\n",
+ false,
+ "unnamed package is not allowed in named modules");
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
index 59f8347..0d2d7a5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
@@ -5355,4 +5355,145 @@
"----------\n",
options);
}
+public void testBug473317() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // using diamond
+ Map<String, String> compilerOptions = getCompilerOptions();
+ compilerOptions.put(JavaCore.COMPILER_PB_SYNTHETIC_ACCESS_EMULATION, JavaCore.IGNORE);
+ runLeakTest(
+ new String[] {
+ "AutoCloseableEnhancedForTest.java",
+ "import java.util.Iterator;\n" +
+ "\n" +
+ "public class AutoCloseableEnhancedForTest\n" +
+ "{\n" +
+ " private static class MyIterator<T> implements Iterator<T>\n" +
+ " {\n" +
+ " private T value;\n" +
+ " \n" +
+ " public MyIterator(T value)\n" +
+ " {\n" +
+ " this.value = value;\n" +
+ " }\n" +
+ " \n" +
+ " @Override\n" +
+ " public boolean hasNext()\n" +
+ " {\n" +
+ " return false;\n" +
+ " }\n" +
+ "\n" +
+ " @Override\n" +
+ " public T next()\n" +
+ " {\n" +
+ " return value;\n" +
+ " }\n" +
+ " }\n" +
+ " \n" +
+ " private static class MyIterable<T> implements Iterable<T>, AutoCloseable\n" +
+ " {\n" +
+ " @Override\n" +
+ " public Iterator<T> iterator()\n" +
+ " {\n" +
+ " return new MyIterator<>(null);\n" +
+ " }\n" +
+ " \n" +
+ " @Override\n" +
+ " public void close() throws Exception\n" +
+ " {\n" +
+ " }\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args)\n" +
+ " {\n" +
+ " // Not flagged as \"never closed.\"\n" +
+ " for (Object value : new MyIterable<>())\n" +
+ " {\n" +
+ " System.out.println(String.valueOf(value));\n" +
+ " \n" +
+ " break;\n" +
+ " }\n" +
+ " \n" +
+ " // Flagged as \"never closed.\"\n" +
+ " MyIterable<Object> iterable = new MyIterable<>();\n" +
+ " \n" +
+ " for (Object value : iterable)\n" +
+ " {\n" +
+ " System.out.println(String.valueOf(value));\n" +
+ " \n" +
+ " break;\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in AutoCloseableEnhancedForTest.java (at line 44)\n" +
+ " for (Object value : new MyIterable<>())\n" +
+ " ^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" +
+ "----------\n" +
+ "2. WARNING in AutoCloseableEnhancedForTest.java (at line 52)\n" +
+ " MyIterable<Object> iterable = new MyIterable<>();\n" +
+ " ^^^^^^^^\n" +
+ "Resource leak: \'iterable\' is never closed\n" +
+ "----------\n",
+ compilerOptions);
+}
+public void testBug541705() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // uses diamond
+ Runner runner = new Runner();
+ runner.customOptions = getCompilerOptions();
+ runner.customOptions.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runner.testFiles = new String[] {
+ "Test.java",
+ "import java.util.*;\n" +
+ "import java.util.zip.*;\n" +
+ "import java.io.*;\n" +
+ "public class Test {\n" +
+ " private static HashMap<String, ZipFile> fgZipFileCache = new HashMap<>(5);\n" +
+ " public static void closeArchives() {\n" +
+ " synchronized (fgZipFileCache) {\n" +
+ " for (ZipFile file : fgZipFileCache.values()) {\n" +
+ " synchronized (file) {\n" +
+ " try {\n" +
+ " file.close();\n" +
+ " } catch (IOException e) {\n" +
+ " System.out.println(e);\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " fgZipFileCache.clear();\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ };
+ runner.runConformTest();
+}
+public void testBug541705b() {
+ if (this.complianceLevel < ClassFileConstants.JDK9) return; // variable used in t-w-r
+ Runner runner = new Runner();
+ runner.customOptions = getCompilerOptions();
+ runner.customOptions.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ runner.testFiles = new String[] {
+ "Test.java",
+ "import java.util.*;\n" +
+ "import java.util.zip.*;\n" +
+ "import java.io.*;\n" +
+ "public class Test {\n" +
+ " private static HashMap<String, ZipFile> fgZipFileCache = new HashMap<>(5);\n" +
+ " public static void closeArchives() {\n" +
+ " synchronized (fgZipFileCache) {\n" +
+ " for (ZipFile file : fgZipFileCache.values()) {\n" +
+ " synchronized (file) {\n" +
+ " try (file) {\n" +
+ " } catch (IOException e) {\n" +
+ " System.out.println(e);\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " fgZipFileCache.clear();\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ };
+ runner.runConformTest();
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
index 283ad4e..7991fa0 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
@@ -405,6 +405,10 @@
if (version.startsWith("1.8.0_")) {
int build = Integer.parseInt(version.substring("1.8.0_".length()));
reflectNestedClassUseDollar = build >= 171;
+ } else if (version.startsWith("1.8.0-")) {
+ // Some versions start with 1.8.0- but don't have build qualifier.
+ // Just assume they are > 171 build. Nothing much can be done.
+ reflectNestedClassUseDollar = true;
} else {
throw new IllegalStateException("Unrecognized Java version: "+version);
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
index 4590978..6523f0e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
@@ -5723,7 +5723,7 @@
*/
public void testBug298844a() {
setFormatLineCommentOnFirstColumn();
- this.formatterPrefs.insert_new_line_in_empty_method_body = false;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
String source =
"public class X01 {\n" +
"public X01() {\n" +
@@ -5739,7 +5739,7 @@
);
}
public void testBug298844b() {
- this.formatterPrefs.insert_new_line_in_empty_method_body = false;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
String source =
"public class X02 {\n" +
"public void foo() {\n" +
@@ -11767,7 +11767,7 @@
* https://bugs.eclipse.org/475793 - [formatter] Incorrect whitespace after lambda block
*/
public void testBug475793() {
- this.formatterPrefs.insert_new_line_in_empty_block = false;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
String source =
"public class C {\r\n" +
" public void f() {\r\n" +
@@ -11786,7 +11786,7 @@
* https://bugs.eclipse.org/475746 - [formatter] insert-space rules sometimes ignored with anonymous subclass or when Annotations present
*/
public void testBug475746() {
- this.formatterPrefs.insert_new_line_in_empty_block = false;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
this.formatterPrefs.insert_space_after_opening_paren_in_method_invocation = true;
this.formatterPrefs.insert_space_before_closing_paren_in_method_invocation = true;
this.formatterPrefs.insert_space_after_opening_paren_in_method_declaration = true;
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
index bd7bb18..f027f9b 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
@@ -645,7 +645,7 @@
public void test041() {
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_type_declaration = false;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test041", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -653,7 +653,7 @@
public void test042() {
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.number_of_empty_lines_to_preserve = 0;
- preferences.insert_new_line_in_empty_type_declaration = false;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
preferences.insert_space_before_opening_brace_in_block = true;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test042", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
@@ -662,7 +662,7 @@
public void test043() {
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_type_declaration = false;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test043", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -1940,10 +1940,10 @@
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.number_of_empty_lines_to_preserve = 0;
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test173", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -1954,10 +1954,10 @@
public void test174() {
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test174", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -1969,10 +1969,9 @@
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.number_of_empty_lines_to_preserve = 0;
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = true;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test175", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -1983,10 +1982,9 @@
public void test176() {
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = true;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test176", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -1997,10 +1995,9 @@
public void test177() {
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test177", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -2011,10 +2008,9 @@
public void test178() {
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = true;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test178", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -2025,10 +2021,9 @@
public void test179() {
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = true;
- preferences.insert_new_line_in_empty_type_declaration = true;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test179", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -2039,10 +2034,9 @@
public void test180() {
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test180", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -4293,10 +4287,9 @@
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.number_of_empty_lines_to_preserve = 0;
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test319", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -4305,10 +4298,9 @@
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.number_of_empty_lines_to_preserve = 0;
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test320", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -4317,10 +4309,9 @@
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.number_of_empty_lines_to_preserve = 0;
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test321", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -4329,10 +4320,9 @@
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.number_of_empty_lines_to_preserve = 0;
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = true;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test322", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -4341,10 +4331,10 @@
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
preferences.number_of_empty_lines_to_preserve = 0;
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = false;
- preferences.insert_new_line_in_empty_method_body = false;
- preferences.insert_new_line_in_empty_block = false;
+ preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test323", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -4614,7 +4604,7 @@
preferences.tab_char = DefaultCodeFormatterOptions.SPACE;
preferences.blank_lines_before_method = 1;
preferences.blank_lines_before_first_class_body_declaration = 1;
- preferences.insert_new_line_in_empty_method_body = false;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test347", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -4631,7 +4621,7 @@
preferences.tab_char = DefaultCodeFormatterOptions.SPACE;
preferences.blank_lines_before_method = 1;
preferences.blank_lines_before_first_class_body_declaration = 1;
- preferences.insert_new_line_in_empty_method_body = false;
+ preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
runTest(codeFormatter, "test348", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
}
@@ -7273,9 +7263,9 @@
Map options = DefaultCodeFormatterConstants.getJavaConventionsSettings();
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_type_declaration = true;
- preferences.insert_new_line_in_empty_enum_constant = false;
- preferences.insert_new_line_in_empty_enum_declaration = false;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ preferences.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
preferences.tab_size = 4;
Hashtable javaCoreOptions = JavaCore.getOptions();
try {
@@ -7303,9 +7293,9 @@
Map options = DefaultCodeFormatterConstants.getJavaConventionsSettings();
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_type_declaration = true;
- preferences.insert_new_line_in_empty_enum_constant = false;
- preferences.insert_new_line_in_empty_enum_declaration = true;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ preferences.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
preferences.tab_size = 4;
Hashtable javaCoreOptions = JavaCore.getOptions();
try {
@@ -7333,9 +7323,9 @@
Map options = DefaultCodeFormatterConstants.getJavaConventionsSettings();
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_type_declaration = true;
- preferences.insert_new_line_in_empty_enum_constant = true;
- preferences.insert_new_line_in_empty_enum_declaration = false;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ preferences.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ preferences.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
preferences.tab_size = 4;
Hashtable javaCoreOptions = JavaCore.getOptions();
try {
@@ -7363,9 +7353,9 @@
Map options = DefaultCodeFormatterConstants.getJavaConventionsSettings();
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
preferences.tab_char = DefaultCodeFormatterOptions.TAB;
- preferences.insert_new_line_in_empty_type_declaration = true;
- preferences.insert_new_line_in_empty_enum_constant = true;
- preferences.insert_new_line_in_empty_enum_declaration = true;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ preferences.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ preferences.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
preferences.tab_size = 4;
Hashtable javaCoreOptions = JavaCore.getOptions();
try {
@@ -8970,8 +8960,8 @@
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
preferences.indent_body_declarations_compare_to_annotation_declaration_header = false;
preferences.indent_body_declarations_compare_to_type_header = true;
- preferences.insert_new_line_in_empty_annotation_declaration = false;
- preferences.insert_new_line_in_empty_type_declaration = true;
+ preferences.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
Hashtable javaCoreOptions = JavaCore.getOptions();
try {
Hashtable newJavaCoreOptions = JavaCore.getOptions();
@@ -8996,8 +8986,8 @@
DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
preferences.indent_body_declarations_compare_to_annotation_declaration_header = true;
preferences.indent_body_declarations_compare_to_type_header = false;
- preferences.insert_new_line_in_empty_annotation_declaration = true;
- preferences.insert_new_line_in_empty_type_declaration = false;
+ preferences.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
Hashtable javaCoreOptions = JavaCore.getOptions();
try {
Hashtable newJavaCoreOptions = JavaCore.getOptions();
@@ -14372,4 +14362,199 @@
String input = getCompilationUnit("Formatter", "", "test131292", "in.java").getSource();
formatSource(input, getCompilationUnit("Formatter", "", "test131292", "F_out.java").getSource());
}
+
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973a() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_1_8);
+ this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+ this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+ String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+ formatSource(input, getCompilationUnit("Formatter", "", "test205973", "A_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973b() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_1_8);
+ this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_simple_getter_setter_on_one_line = true;
+ this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+ String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+ formatSource(input, getCompilationUnit("Formatter", "", "test205973", "B_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973c() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_1_8);
+ this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+ this.formatterPrefs.keep_guardian_clause_on_one_line = true;
+ String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+ formatSource(input, getCompilationUnit("Formatter", "", "test205973", "C_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973d() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_1_8);
+ this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+ this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+ String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+ formatSource(input, getCompilationUnit("Formatter", "", "test205973", "D_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973e() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_1_8);
+ this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_simple_getter_setter_on_one_line = true;
+ this.formatterPrefs.keep_guardian_clause_on_one_line = true;
+ String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+ formatSource(input, getCompilationUnit("Formatter", "", "test205973", "E_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973f() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_1_8);
+ this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+ this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+ String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+ formatSource(input, getCompilationUnit("Formatter", "", "test205973", "F_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973g() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_1_8);
+ this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+ this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+ String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+ formatSource(input, getCompilationUnit("Formatter", "", "test205973", "G_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973h() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_1_8);
+ this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+ this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+ this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+ this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+ this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+ this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+ this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+ this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+ this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+ this.formatterPrefs.align_type_members_on_columns = true;
+ this.formatterPrefs.align_variable_declarations_on_columns = true;
+ this.formatterPrefs.align_assignment_statements_on_columns = true;
+ String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+ formatSource(input, getCompilationUnit("Formatter", "", "test205973", "H_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973i() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_1_8);
+ this.formatterPrefs.page_width = 50;
+ this.formatterPrefs.use_tabs_only_for_leading_indentations = true;
+ this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+ this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+ this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+ String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+ formatSource(input, getCompilationUnit("Formatter", "", "test205973", "I_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973j() throws JavaModelException {
+ setComplianceLevel(CompilerOptions.VERSION_1_8);
+ this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ String input = getCompilationUnit("Formatter", "", "test205973", "J_in.java").getSource();
+ formatSource(input, getCompilationUnit("Formatter", "", "test205973", "J_out.java").getSource());
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
index 491e60e..1ad40ca 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
@@ -3495,6 +3495,16 @@
IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
null);
} catch (CoreException e) {
+ logError("exception occurred while waiting on indexing", e);
+ }
+ }
+
+ private static void logError(String errorMessage, CoreException e) {
+ Plugin plugin = JavaCore.getPlugin();
+ if (plugin != null) {
+ ILog log = plugin.getLog();
+ Status status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, errorMessage, e);
+ log.log(status);
}
}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
index 607c65b..ba4462e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
@@ -25,6 +25,7 @@
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
@@ -37,6 +38,7 @@
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
@@ -1903,12 +1905,18 @@
}
if (isJRE12) return;
try {
- createJava9Project("Test", new String[]{"src"});
+ IJavaProject prj = createJava9Project("Test", new String[]{"src"});
String moduleSrc =
"module test {\n" +
" requires oracle.net;\n" +
"}\n";
createFile("/Test/src/module-info.java", moduleSrc);
+ prj.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ IMarker[] markers = prj.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ if (markers.length == 1 && markers[0].toString().contains("oracle.net cannot be resolved to a module")) {
+ System.out.println("Skipping "+getClass().getName()+".testModule2() because module oracle.net is unavailable");
+ return; // oracle.net is missing from openjdk builds
+ }
ICompilationUnit unit = getCompilationUnit("/Test/src/module-info.java");
int start = moduleSrc.indexOf("oracle.net");
int length = "oracle.net".length();
@@ -1927,4 +1935,55 @@
deleteProject("Test");
}
}
+public void testModule2b() throws CoreException, IOException {
+ if (!isJRE9) {
+ System.err.println(this.getClass().getName()+'.'+getName()+" needs a Java 9 JRE - skipped");
+ return;
+ }
+ try {
+ // create project with incomplete source attachment:
+ String javaHome = System.getProperty("java.home") + File.separator;
+ Path bootModPath = new Path(javaHome +"/lib/jrt-fs.jar");
+ createSourceZip(
+ new String[] {
+ "java.base/module-info.java",
+ "module java.base {}\n",
+ "java.se.ee/module-info.java",
+ "module java.se.ee {}\n"
+ },
+ getWorkspacePath()+"/Test/src.zip");
+ Path sourceAttachment = new Path("/Test/src.zip");
+ IClasspathEntry jrtEntry;
+ jrtEntry = JavaCore.newLibraryEntry(bootModPath, sourceAttachment, null, null, null, false);
+ IJavaProject project = this.createJavaProject("Test", new String[] {"src"}, new String[0],
+ new String[0], "bin", "9");
+ IClasspathEntry[] old = project.getRawClasspath();
+ IClasspathEntry[] newPath = new IClasspathEntry[old.length +1];
+ System.arraycopy(old, 0, newPath, 0, old.length);
+ newPath[old.length] = jrtEntry;
+ project.setRawClasspath(newPath, null);
+ //
+ String moduleSrc =
+ "module test {\n" +
+ " requires java.desktop;\n" +
+ "}\n";
+ createFile("/Test/src/module-info.java", moduleSrc);
+ ICompilationUnit unit = getCompilationUnit("/Test/src/module-info.java");
+ int start = moduleSrc.indexOf("java.desktop");
+ int length = "java.desktop".length();
+ IJavaElement[] elements = unit.codeSelect(start, length);
+ assertEquals("expected #elements", 1, elements.length);
+
+ IModuleDescription javaDesktop = (IModuleDescription) elements[0];
+ IModularClassFile cf = (IModularClassFile) javaDesktop.getClassFile();
+ assertSourceEquals(
+ "Unexpected source for class file java.desktop/module-info.class",
+ null,
+ cf.getSource());
+ ISourceRange javadocRange = javaDesktop.getJavadocRange();
+ assertEquals("javadoc from source", null, javadocRange);
+ } finally {
+ deleteProject("Test");
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Bug376673Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Bug376673Test.java
new file mode 100644
index 0000000..010f0de
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Bug376673Test.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaProject;
+
+import junit.framework.Test;
+
+public class Bug376673Test extends ModifyingResourceTests {
+
+ public Bug376673Test(String name) {
+ super(name);
+ this.endChar = "";
+ }
+
+ public static Test suite() {
+ return buildModelTestSuite(Bug376673Test.class);
+ }
+
+ /**
+ * An extra test for bug 413114 in the context of bug 376673.
+ * We want to know whether we can compile with when using a class from a jar as created in
+ * {@link org.eclipse.jdt.core.tests.model.JavaSearchBugsTests2#testBug376673e()}.
+ */
+ public void testBug376673() throws Exception {
+ try {
+ if ("macosx".equals(System.getProperty("osgi.os"))) {
+ return;
+ }
+ IJavaProject p = createJavaProject("P", new String[] { "src" }, new String[] { "/P/lib376673.jar", "JCL17_LIB" }, "bin", "1.7");
+
+ org.eclipse.jdt.core.tests.util.Util.createJar(
+ new String[] { "p\uD842\uDF9F/i\uD842\uDF9F/Test.java",
+ "package p\uD842\uDF9F.i\uD842\uDF9F;\n" + "public class Test{}\n" },
+ p.getProject().getLocation().append("lib376673.jar").toOSString(), "1.7");
+
+ createFolder("/P/src/pkg");
+ String[] classFileContent = new String[] {
+ "package pkg;",
+ "class UseJarClass {",
+ " public p\uD842\uDF9F.i\uD842\uDF9F.Test test;",
+ "}",
+ };
+ IFile file = createFile("/P/src/pkg/UseJarClass.java", String.join(System.lineSeparator(), classFileContent), "UTF-8");
+ file.setCharset("UTF-8", null);
+ refresh(p);
+ waitForAutoBuild();
+ waitUntilIndexesReady();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ List<String> errors = new ArrayList<>();
+ StringBuilder markersToString = new StringBuilder();
+ for (IMarker marker : markers) {
+
+ Integer severity = (Integer) marker.getAttribute(IMarker.SEVERITY);
+ String message = (String) marker.getAttribute(IMarker.MESSAGE);
+ if (severity.intValue() == IMarker.SEVERITY_ERROR) {
+ errors.add(message);
+ }
+
+ markersToString.append("Marker with severity: ");
+ markersToString.append(severity);
+ markersToString.append(", and message: ");
+ markersToString.append(message);
+ markersToString.append(", at location: ");
+ markersToString.append(marker.getAttribute(IMarker.LOCATION));
+ markersToString.append(", at line: ");
+ markersToString.append(marker.getAttribute(IMarker.LINE_NUMBER));
+ }
+ assertEquals("expected no markers on test project, all markers are:" + System.lineSeparator() + markersToString,
+ Collections.emptyList(), errors);
+ } finally {
+ deleteProject("P");
+ }
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java
index e7d0003..b1dee23 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java
@@ -126,6 +126,9 @@
assertTrue(JavaCore.compareJavaVersions("9", "9.1.2") == 0);
assertTrue(JavaCore.compareJavaVersions("12", "11") > 0);
assertTrue(JavaCore.compareJavaVersions("12", "1.5") > 0);
+ String latest = JavaCore.latestSupportedJavaVersion();
+ String latestPlus = "" + (Integer.parseInt(latest) + 1);
+ assertTrue(JavaCore.compareJavaVersions(latest, latestPlus) == 0);
}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
index d08d5a1..a4fe9ca 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
index c28aa90..2c92682 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
@@ -41,6 +41,7 @@
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IProblemRequestor;
import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.CompilationUnit;
@@ -94,6 +95,16 @@
deleteProject("P1");
}
+ IClasspathAttribute[] moduleAttribute() {
+ return new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
+ }
+ void addModularProjectEntry(IJavaProject project, IJavaProject depProject) throws JavaModelException {
+ addClasspathEntry(project, JavaCore.newProjectEntry(depProject.getPath(), null, false, moduleAttribute(), false));
+ }
+ void addModularLibraryEntry(IJavaProject project, String libraryPath) throws JavaModelException {
+ addLibraryEntry(project, new Path(libraryPath), null, null, null, null, moduleAttribute(), false);
+ }
+
// Test that the java.base found as a module package fragment root in the project
public void test001() throws CoreException {
if (!isJRE9) return;
@@ -1837,8 +1848,8 @@
deleteProject("com.greetings");
}
}
- // Changes to implicit dependencies should be reflected
- public void test_ModuleSourcePath_implicitdeps2() throws CoreException {
+ // Changes to implicit dependencies should be reflected // FIXME: container JavaCore.MODULE_PATH_CONTAINER_ID is unreliable
+ public void _test_ModuleSourcePath_implicitdeps2() throws CoreException {
if (!isJRE9) return;
try {
String[] sources = new String[] {
@@ -6279,21 +6290,28 @@
if (!isJRE9 || isJRE12) return;
ClasspathJrt.resetCaches();
try {
- IJavaProject javaProject = createJava9Project("mod1", new String[] {"src"});
+ // jdk.rmic is not be visible to code in an unnamed module, but using requires we can see the module.
+ // only, there's nothing exported from it (which is why JEP 261 hides it from unnamed), so we --add-reads:
+ IClasspathAttribute[] attrs = new IClasspathAttribute[] {
+ JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "jdk.rmic/sun.rmi.rmic=mod1")
+ };
+ IJavaProject javaProject = createJava9ProjectWithJREAttributes("mod1", new String[] {"src"}, attrs);
String srcMod =
- "@SuppressWarnings(\"removal\")\n" + // javax.xml.ws.annotation is deprecated for removal
"module mod1 {\n" +
" exports com.mod1.pack1;\n" +
- " requires java.xml.ws.annotation;\n" +
+ " requires jdk.rmic;\n" +
"}";
createFile("/mod1/src/module-info.java",
srcMod);
createFolder("/mod1/src/com/mod1/pack1");
String srcX =
"package com.mod1.pack1;\n" +
- "@javax.annotation.Generated(\"com.acme.generator.CodeGen\")\n" +
+ "import sun.rmi.rmic.Main;\n" +
"public class Dummy {\n" +
+ " String test() {\n" +
+ " return Main.getString(\"in\");\n" +
+ " }\n" +
"}";
createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX);
@@ -6318,6 +6336,92 @@
}
}
+ public void testBug526054b() throws Exception {
+ if (!isJRE9) return;
+ ClasspathJrt.resetCaches();
+ try {
+ // one project can see jdk.rmic/sun.rmi.rmic
+ IClasspathAttribute[] attrs = new IClasspathAttribute[] {
+ JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "jdk.rmic/sun.rmi.rmic=mod1")
+ };
+ createJava9ProjectWithJREAttributes("mod1", new String[] {"src"}, attrs);
+
+ String srcMod1 =
+ "module mod1 {\n" +
+ " exports com.mod1.pack1;\n" +
+ " requires jdk.rmic;\n" +
+ "}";
+ createFile("/mod1/src/module-info.java",
+ srcMod1);
+ createFolder("/mod1/src/com/mod1/pack1");
+ String srcX1 =
+ "package com.mod1.pack1;\n" +
+ "import sun.rmi.rmic.Constants;\n" + // this should never be complained against due to above add-exports.
+ "public class Dummy implements Constants {\n" +
+ "}";
+ createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX1);
+
+ // second project cannot see jdk.rmic/sun.rmi.rmic:
+ createJava9Project("mod2", new String[] {"src"});
+
+ String srcMod2 =
+ "module mod2 {\n" +
+ " exports com.mod2.pack1;\n" +
+ " requires jdk.rmic;\n" +
+ "}";
+ createFile("/mod2/src/module-info.java",
+ srcMod2);
+ createFolder("/mod2/src/com/mod2/pack1");
+ String srcX2 =
+ "package com.mod2.pack1;\n" +
+ "import sun.rmi.rmic.Main;\n" +
+ "public class Dummy {\n" +
+ " String test() {\n" +
+ " return Main.getString(\"in\");\n" +
+ " }\n" +
+ "}";
+ createFile("/mod2/src/com/mod2/pack1/Dummy.java", srcX2);
+
+ // check first:
+ this.problemRequestor.initialize(srcX1.toCharArray());
+ getWorkingCopy("/mod1/src/com/mod1/pack1/Dummy.java", srcX1, true);
+ assertProblems("Dummy in mod1 should have no problems",
+ "----------\n" +
+ "----------\n",
+ this.problemRequestor);
+
+ // check second:
+ this.problemRequestor.initialize(srcX2.toCharArray());
+ getWorkingCopy("/mod2/src/com/mod2/pack1/Dummy.java", srcX2, true);
+ assertProblems("Dummy in mod2 should have problems",
+ "----------\n" +
+ "1. ERROR in /mod2/src/com/mod2/pack1/Dummy.java (at line 2)\n" +
+ " import sun.rmi.rmic.Main;\n" +
+ " ^^^^^^^^^^^^^^^^^\n" +
+ "The type sun.rmi.rmic.Main is not accessible\n" +
+ "----------\n" +
+ "2. ERROR in /mod2/src/com/mod2/pack1/Dummy.java (at line 5)\n" +
+ " return Main.getString(\"in\");\n" +
+ " ^^^^\n" +
+ "Main cannot be resolved\n" +
+ "----------\n",
+ this.problemRequestor);
+
+ // check both in a combined build
+ getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null);
+ getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ IMarker[] markers = getWorkspace().getRoot().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ sortMarkers(markers);
+ assertMarkers("Unexpected markers",
+ "The type sun.rmi.rmic.Main is not accessible\n" +
+ "Main cannot be resolved",
+ markers);
+ } finally {
+ deleteProject("mod1");
+ deleteProject("mod2");
+ }
+ }
+
public void testBug525918() throws CoreException {
if (!isJRE9) return;
try {
@@ -7039,6 +7143,173 @@
this.deleteProject("Bug540904");
}
}
+ public void testBug540788() throws Exception {
+ if (!isJRE9) return;
+ try {
+ // project common:
+ IJavaProject common = createJava9Project("Bug540788.common", new String[] { "src/main/java" });
+ createSourceFiles(common,
+ new String[] {
+ "src/main/java/module-info.java",
+ "module org.sheepy.common {\n" +
+ " requires transitive org.eclipse.emf.common;\n" +
+ " requires transitive org.eclipse.emf.ecore;\n" +
+ "}\n"
+ });
+ IFolder libs = createFolder("/Bug540788.common/libs");
+ String emfCommonPath = libs.getLocation()+"/org.eclipse.emf.common.jar";
+ Util.createJar(
+ new String[] {
+ "src/org/eclipse/emf/common/Foo.java",
+ "package org.eclipse.emf.common;\n" +
+ "public interface Foo {\n" +
+ "}",
+ },
+ null,
+ new HashMap<>(),
+ null,
+ emfCommonPath);
+ addModularLibraryEntry(common, emfCommonPath);
+ String ecorePath = libs.getLocation()+"/org.eclipse.emf.ecore.jar";
+ Util.createJar(
+ new String[] {
+ "src/org/eclipse/emf/ecore/EObject.java",
+ "package org.eclipse.emf.ecore;\n" +
+ "public interface EObject {\n" +
+ "}",
+ },
+ null,
+ new HashMap<>(),
+ null,
+ ecorePath);
+ addModularLibraryEntry(common, ecorePath);
+ // project vulkan:
+ IJavaProject vulkan = createJava9Project("Bug540788.vulkan", new String[] { "src/main/java" });
+ createSourceFiles(vulkan,
+ new String[] {
+ "src/main/java/module-info.java",
+ "module org.sheepy.vulkan {\n" +
+ " requires transitive org.sheepy.common;\n" +
+ " exports org.sheepy.vulkan.model.resource;\n" +
+ "}\n",
+ "src/main/java/org/sheepy/vulkan/model/resource/Resource.java",
+ "package org.sheepy.vulkan.model.resource;\n" +
+ "import org.eclipse.emf.ecore.EObject;\n" +
+ "public interface Resource extends EObject {\n" +
+ "}\n",
+ "src/main/java/org/sheepy/vulkan/model/resource/VulkanBuffer.java",
+ "package org.sheepy.vulkan.model.resource;\n" +
+ "public interface VulkanBuffer extends Resource {\n" +
+ "}\n",
+ });
+ addModularProjectEntry(vulkan, common);
+ addModularLibraryEntry(vulkan, emfCommonPath);
+ addModularLibraryEntry(vulkan, ecorePath);
+ // project vulkan.demo
+ IJavaProject vulkan_demo = createJava9Project("Bug540788.vulkan.demo", new String[] { "src/main/java" });
+ createSourceFiles(vulkan_demo,
+ new String[] {
+ "src/main/java/module-info.java",
+ "module org.sheepy.vulkan.demo {\n" +
+ " exports org.sheepy.vulkan.demo.model;\n" +
+ " requires org.sheepy.vulkan;\n" +
+ "}\n",
+ "src/main/java/org/sheepy/vulkan/demo/model/UniformBuffer.java",
+ "package org.sheepy.vulkan.demo.model;\n" +
+ "import org.sheepy.vulkan.model.resource.VulkanBuffer;\n" +
+ "public interface UniformBuffer extends VulkanBuffer {\n" +
+ "}\n",
+ });
+ addModularProjectEntry(vulkan_demo, vulkan);
+ addModularProjectEntry(vulkan_demo, common);
+ addModularLibraryEntry(vulkan_demo, emfCommonPath);
+ addModularLibraryEntry(vulkan_demo, ecorePath);
+
+ getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ IMarker[] markers = vulkan_demo.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers", "", markers);
+ } finally {
+ deleteProject("Bug540788.common");
+ deleteProject("Bug540788.vulkan");
+ deleteProject("Bug540788.vulkan.demo");
+ }
+ }
+ public void testBug541015() throws Exception {
+ try {
+ IJavaProject m1 = createJava9Project("m1", new String[] { "src" });
+ createSourceFiles(m1,
+ new String[] {
+ "src/module-info.java",
+ "module m1 { exports org.p1; }\n",
+ "src/org/p1/T1.java",
+ "package org.p1;\n" +
+ "public class T1 {}\n"
+ });
+ IJavaProject m2 = createJava9Project("m2", new String[] { "src" });
+ createSourceFiles(m2,
+ new String[] {
+ "src/module-info.java",
+ "module m2 { exports org.p1; }\n",
+ "src/org/p1/T1.java",
+ "package org.p1;\n" +
+ "public class T1 {}\n"
+ });
+ IJavaProject m3 = createJava9Project("m3", new String[] { "src" });
+ createSourceFiles(m3,
+ new String[] {
+ "src/module-info.java",
+ "module m3 { exports org.p1; }\n",
+ "src/org/p1/T1.java",
+ "package org.p1;\n" +
+ "public class T1 {}\n"
+ });
+ IJavaProject unnamed = createJava9Project("unnamed", new String[] { "src" });
+ String testSource = "package test;\n" +
+ "import org.p1.T1;\n" +
+ "public class Test {\n" +
+ " T1 t1;\n" +
+ "}\n";
+ createSourceFiles(unnamed,
+ new String[] {
+ "src/test/Test.java",
+ testSource
+ });
+ addModularProjectEntry(unnamed, m1);
+ addModularProjectEntry(unnamed, m2);
+ addModularProjectEntry(unnamed, m3);
+
+ getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
+ IMarker[] markers = unnamed.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ sortMarkers(markers);
+ assertMarkers("Unexpected markers",
+ "The import org.p1.T1 cannot be resolved\n" +
+ "T1 cannot be resolved to a type",
+ markers);
+
+ char[] sourceChars = testSource.toCharArray();
+ this.problemRequestor.initialize(sourceChars);
+ getCompilationUnit("/unnamed/src/test/Test.java").getWorkingCopy(this.wcOwner, null);
+ assertProblems(
+ "Unexpected problems",
+ "----------\n" +
+ "1. ERROR in /unnamed/src/test/Test.java (at line 2)\n" +
+ " import org.p1.T1;\n" +
+ " ^^^^^^^^^\n" +
+ "The import org.p1.T1 cannot be resolved\n" +
+ "----------\n" +
+ "2. ERROR in /unnamed/src/test/Test.java (at line 4)\n" +
+ " T1 t1;\n" +
+ " ^^\n" +
+ "T1 cannot be resolved to a type\n" +
+ "----------\n",
+ this.problemRequestor);
+ } finally {
+ deleteProject("m1");
+ deleteProject("m2");
+ deleteProject("m3");
+ deleteProject("unnamed");
+ }
+ }
protected void assertNoErrors() throws CoreException {
for (IProject p : getWorkspace().getRoot().getProjects()) {
int maxSeverity = p.findMaxProblemSeverity(null, true, IResource.DEPTH_INFINITE);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
index 3695005..1333386 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
@@ -71,6 +71,7 @@
allClasses.add(JavaSearchScopeTests.class);
allClasses.add(MatchingRegionsTest.class);
allClasses.add(JavaIndexTests.class);
+ allClasses.add(Bug376673Test.class);
// Reset forgotten subsets of tests
TestCase.TESTS_PREFIX = null;
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/A_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/A_out.java
new file mode 100644
index 0000000..89aa366
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/A_out.java
@@ -0,0 +1,160 @@
+class Example {
+ public void example() {
+ for (int i = 0; i < 10; i++) {}
+ int a = 10;
+ while (a-- > 0) {
+ System.out.println(a);
+ }
+ do {
+ a += 2;
+ System.out.println(a);
+ } while (a < 50);
+ }
+}
+
+class Example {
+ public String example(int a) {
+ if (a < 0) {
+ throw new IllegalArgumentException();
+ }
+ if (a == 0) {
+ return null;
+ }
+ if (false) {}
+ if (a % 3 == 0) {
+ System.out.println("fizz");
+ }
+ if (a % 5 == 0) {
+ System.out.println("buzz");
+ return "";
+ }
+ return Integer.toString(a);
+ }
+}
+
+class Example {
+ Runnable emptyLambda = () -> {};
+ Runnable emptyLambda2 = () -> {};
+ Runnable tinyLambda = () -> {
+ doSomething();
+ };
+ Runnable smallLambda = () -> {
+ doFirstThing();
+ doSecondThing();
+ };
+}
+
+class Example {
+ static {
+ }
+
+ void foo() {
+ if (true) {
+ } else {
+ }
+ synchronized (this) {
+ }
+ try {
+ } finally {
+ }
+
+ labeled: {
+ }
+ }
+}
+
+public class Example {
+ private int something;
+
+ public int getSomething() {
+ return something;
+ }
+
+ public void setSomehing(int something) {
+ this.something = something;
+ }
+
+ public void doNoting() {
+ }
+
+ public void doOneThing() {
+ System.out.println();
+ }
+
+ public void doMoreThings() {
+ something = 4;
+ doOneThing();
+ doOneThing();
+ }
+}
+
+public class EmptyClass {
+}
+
+public class TinyClass {
+ int a;
+}
+
+public class SmallClass {
+ int a;
+ String b;
+}
+
+public class AnonymousClasses {
+ EmptyClass emptyAnonymous = new EmptyClass() {};
+ TinyClass tinyAnonymous = new TinyClass() {
+ String b;
+ };
+ Object o = new SmallClass() {
+ int a;
+
+ int getA() {
+ return a;
+ }
+ };
+}
+
+public enum EmptyEnum {
+}
+
+public enum TinyEnum {
+ A;
+}
+
+public enum SmallEnum {
+ VALUE(0);
+ SmallEnum(int val) {
+ };
+}
+
+public enum EnumConstants {
+ EMPTY {
+ },
+ TINY {
+ int getVal() {
+ return 2;
+ }
+ },
+ SMALL {
+ int val = 3;
+
+ int getVal() {
+ return 3;
+ }
+ };
+ int getVal() {
+ return 1;
+ }
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface {
+ void run();
+}
+
+public @interface SmallInteface {
+ int toA();
+
+ String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/B_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/B_out.java
new file mode 100644
index 0000000..4c112b8
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/B_out.java
@@ -0,0 +1,145 @@
+class Example {
+ public void example() {
+ for (int i = 0; i < 10; i++) {}
+ int a = 10;
+ while (a-- > 0) { System.out.println(a); }
+ do {
+ a += 2;
+ System.out.println(a);
+ } while (a < 50);
+ }
+}
+
+class Example {
+ public String example(int a) {
+ if (a < 0) {
+ throw new IllegalArgumentException();
+ }
+ if (a == 0) {
+ return null;
+ }
+ if (false) {
+ }
+ if (a % 3 == 0) {
+ System.out.println("fizz");
+ }
+ if (a % 5 == 0) {
+ System.out.println("buzz");
+ return "";
+ }
+ return Integer.toString(a);
+ }
+}
+
+class Example {
+ Runnable emptyLambda = () -> {};
+ Runnable emptyLambda2 = () -> {};
+ Runnable tinyLambda = () -> { doSomething(); };
+ Runnable smallLambda = () -> {
+ doFirstThing();
+ doSecondThing();
+ };
+}
+
+class Example {
+ static {
+ }
+
+ void foo() {
+ if (true) {
+ } else {
+ }
+ synchronized (this) {
+ }
+ try {
+ } finally {
+ }
+
+ labeled: {
+ }
+ }
+}
+
+public class Example {
+ private int something;
+
+ public int getSomething() { return something; }
+
+ public void setSomehing(int something) { this.something = something; }
+
+ public void doNoting() {
+ }
+
+ public void doOneThing() {
+ System.out.println();
+ }
+
+ public void doMoreThings() {
+ something = 4;
+ doOneThing();
+ doOneThing();
+ }
+}
+
+public class EmptyClass {
+}
+
+public class TinyClass {
+ int a;
+}
+
+public class SmallClass {
+ int a;
+ String b;
+}
+
+public class AnonymousClasses {
+ EmptyClass emptyAnonymous = new EmptyClass() {
+ };
+ TinyClass tinyAnonymous = new TinyClass() {
+ String b;
+ };
+ Object o = new SmallClass() {
+ int a;
+
+ int getA() { return a; }
+ };
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum {
+ A;
+}
+
+public enum SmallEnum {
+ VALUE(0);
+ SmallEnum(int val) {
+ };
+}
+
+public enum EnumConstants {
+ EMPTY {},
+ TINY {
+ int getVal() { return 2; }
+ },
+ SMALL {
+ int val = 3;
+
+ int getVal() { return 3; }
+ };
+ int getVal() { return 1; }
+}
+
+public @interface EmptyInterface {
+}
+
+public @interface TinyInterface {
+ void run();
+}
+
+public @interface SmallInteface {
+ int toA();
+
+ String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/C_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/C_out.java
new file mode 100644
index 0000000..ec05534
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/C_out.java
@@ -0,0 +1,143 @@
+class Example {
+ public void example() {
+ for (int i = 0; i < 10; i++) {
+ }
+ int a = 10;
+ while (a-- > 0) {
+ System.out.println(a);
+ }
+ do {
+ a += 2;
+ System.out.println(a);
+ } while (a < 50);
+ }
+}
+
+class Example {
+ public String example(int a) {
+ if (a < 0) { throw new IllegalArgumentException(); }
+ if (a == 0) { return null; }
+ if (false) {
+ }
+ if (a % 3 == 0) {
+ System.out.println("fizz");
+ }
+ if (a % 5 == 0) {
+ System.out.println("buzz");
+ return "";
+ }
+ return Integer.toString(a);
+ }
+}
+
+class Example {
+ Runnable emptyLambda = () -> {
+ };
+ Runnable emptyLambda2 = () -> {
+ };
+ Runnable tinyLambda = () -> {
+ doSomething();
+ };
+ Runnable smallLambda = () -> {
+ doFirstThing();
+ doSecondThing();
+ };
+}
+
+class Example {
+ static {}
+
+ void foo() {
+ if (true) {} else {}
+ synchronized (this) {}
+ try {} finally {}
+
+ labeled: {}
+ }
+}
+
+public class Example {
+ private int something;
+
+ public int getSomething() {
+ return something;
+ }
+
+ public void setSomehing(int something) {
+ this.something = something;
+ }
+
+ public void doNoting() {}
+
+ public void doOneThing() {
+ System.out.println();
+ }
+
+ public void doMoreThings() {
+ something = 4;
+ doOneThing();
+ doOneThing();
+ }
+}
+
+public class EmptyClass {}
+
+public class TinyClass {
+ int a;
+}
+
+public class SmallClass {
+ int a;
+ String b;
+}
+
+public class AnonymousClasses {
+ EmptyClass emptyAnonymous = new EmptyClass() {};
+ TinyClass tinyAnonymous = new TinyClass() { String b; };
+ Object o = new SmallClass() {
+ int a;
+
+ int getA() {
+ return a;
+ }
+ };
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum { A; }
+
+public enum SmallEnum {
+ VALUE(0);
+ SmallEnum(int val) {};
+}
+
+public enum EnumConstants {
+ EMPTY {
+ },
+ TINY {
+ int getVal() {
+ return 2;
+ }
+ },
+ SMALL {
+ int val = 3;
+
+ int getVal() {
+ return 3;
+ }
+ };
+ int getVal() {
+ return 1;
+ }
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface { void run(); }
+
+public @interface SmallInteface {
+ int toA();
+
+ String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/D_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/D_out.java
new file mode 100644
index 0000000..a1e2cca
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/D_out.java
@@ -0,0 +1,148 @@
+class Example {
+ public void example() {
+ for (int i = 0; i < 10; i++) {
+ }
+ int a = 10;
+ while (a-- > 0) {
+ System.out.println(a);
+ }
+ do {
+ a += 2;
+ System.out.println(a);
+ } while (a < 50);
+ }
+}
+
+class Example {
+ public String example(int a) {
+ if (a < 0) {
+ throw new IllegalArgumentException();
+ }
+ if (a == 0) {
+ return null;
+ }
+ if (false) {
+ }
+ if (a % 3 == 0) {
+ System.out.println("fizz");
+ }
+ if (a % 5 == 0) {
+ System.out.println("buzz");
+ return "";
+ }
+ return Integer.toString(a);
+ }
+}
+
+class Example {
+ Runnable emptyLambda = () -> {};
+ Runnable emptyLambda2 = () -> {};
+ Runnable tinyLambda = () -> { doSomething(); };
+ Runnable smallLambda = () -> {
+ doFirstThing();
+ doSecondThing();
+ };
+}
+
+class Example {
+ static {}
+
+ void foo() {
+ if (true) {} else {}
+ synchronized (this) {}
+ try {} finally {}
+
+ labeled: {}
+ }
+}
+
+public class Example {
+ private int something;
+
+ public int getSomething() {
+ return something;
+ }
+
+ public void setSomehing(int something) {
+ this.something = something;
+ }
+
+ public void doNoting() {
+ }
+
+ public void doOneThing() {
+ System.out.println();
+ }
+
+ public void doMoreThings() {
+ something = 4;
+ doOneThing();
+ doOneThing();
+ }
+}
+
+public class EmptyClass {}
+
+public class TinyClass { int a; }
+
+public class SmallClass {
+ int a;
+ String b;
+}
+
+public class AnonymousClasses {
+ EmptyClass emptyAnonymous = new EmptyClass() {};
+ TinyClass tinyAnonymous = new TinyClass() { String b; };
+ Object o = new SmallClass() {
+ int a;
+
+ int getA() {
+ return a;
+ }
+ };
+}
+
+public enum EmptyEnum {
+}
+
+public enum TinyEnum {
+ A;
+}
+
+public enum SmallEnum {
+ VALUE(0);
+ SmallEnum(int val) {
+ };
+}
+
+public enum EnumConstants {
+ EMPTY {},
+ TINY {
+ int getVal() {
+ return 2;
+ }
+ },
+ SMALL {
+ int val = 3;
+
+ int getVal() {
+ return 3;
+ }
+ };
+ int getVal() {
+ return 1;
+ }
+}
+
+public @interface EmptyInterface {
+}
+
+public @interface TinyInterface {
+ void run();
+}
+
+public @interface SmallInteface {
+ int toA();
+
+ String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/E_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/E_out.java
new file mode 100644
index 0000000..60cf56f
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/E_out.java
@@ -0,0 +1,127 @@
+class Example {
+ public void example() {
+ for (int i = 0; i < 10; i++) {}
+ int a = 10;
+ while (a-- > 0) { System.out.println(a); }
+ do { a += 2; System.out.println(a); } while (a < 50);
+ }
+}
+
+class Example {
+ public String example(int a) {
+ if (a < 0) { throw new IllegalArgumentException(); }
+ if (a == 0) { return null; }
+ if (false) {}
+ if (a % 3 == 0) {
+ System.out.println("fizz");
+ }
+ if (a % 5 == 0) {
+ System.out.println("buzz");
+ return "";
+ }
+ return Integer.toString(a);
+ }
+}
+
+class Example {
+ Runnable emptyLambda = () -> {
+ };
+ Runnable emptyLambda2 = () -> {
+ };
+ Runnable tinyLambda = () -> {
+ doSomething();
+ };
+ Runnable smallLambda = () -> {
+ doFirstThing();
+ doSecondThing();
+ };
+}
+
+class Example {
+ static {
+ }
+
+ void foo() {
+ if (true) {
+ } else {
+ }
+ synchronized (this) {
+ }
+ try {
+ } finally {
+ }
+
+ labeled: {
+ }
+ }
+}
+
+public class Example {
+ private int something;
+
+ public int getSomething() { return something; }
+
+ public void setSomehing(int something) { this.something = something; }
+
+ public void doNoting() {}
+
+ public void doOneThing() {
+ System.out.println();
+ }
+
+ public void doMoreThings() {
+ something = 4;
+ doOneThing();
+ doOneThing();
+ }
+}
+
+public class EmptyClass {
+}
+
+public class TinyClass {
+ int a;
+}
+
+public class SmallClass {
+ int a;
+ String b;
+}
+
+public class AnonymousClasses {
+ EmptyClass emptyAnonymous = new EmptyClass() {
+ };
+ TinyClass tinyAnonymous = new TinyClass() {
+ String b;
+ };
+ Object o = new SmallClass() {
+ int a;
+
+ int getA() { return a; }
+ };
+}
+
+public enum EmptyEnum {
+}
+
+public enum TinyEnum {
+ A;
+}
+
+public enum SmallEnum {
+ VALUE(0);
+ SmallEnum(int val) {};
+}
+
+public enum EnumConstants {
+ EMPTY {},
+ TINY { int getVal() { return 2; } },
+ SMALL { int val = 3; int getVal() { return 3; } };
+ int getVal() { return 1; }
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface { void run(); }
+
+public @interface SmallInteface { int toA(); String toB(); }
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/F_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/F_out.java
new file mode 100644
index 0000000..012f0e3
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/F_out.java
@@ -0,0 +1,142 @@
+class Example {
+ public void example() {
+ for (int i = 0; i < 10; i++) {}
+ int a = 10;
+ while (a-- > 0) { System.out.println(a); }
+ do {
+ a += 2;
+ System.out.println(a);
+ } while (a < 50);
+ }
+}
+
+class Example {
+ public String example(int a) {
+ if (a < 0) { throw new IllegalArgumentException(); }
+ if (a == 0) { return null; }
+ if (false) {}
+ if (a % 3 == 0) { System.out.println("fizz"); }
+ if (a % 5 == 0) { System.out.println("buzz"); return ""; }
+ return Integer.toString(a);
+ }
+}
+
+class Example {
+ Runnable emptyLambda = () -> {
+ };
+ Runnable emptyLambda2 = () -> {
+ };
+ Runnable tinyLambda = () -> {
+ doSomething();
+ };
+ Runnable smallLambda = () -> {
+ doFirstThing();
+ doSecondThing();
+ };
+}
+
+class Example {
+ static {
+ }
+
+ void foo() {
+ if (true) {
+ } else {
+ }
+ synchronized (this) {
+ }
+ try {
+ } finally {
+ }
+
+ labeled: {
+ }
+ }
+}
+
+public class Example {
+ private int something;
+
+ public int getSomething() {
+ return something;
+ }
+
+ public void setSomehing(int something) {
+ this.something = something;
+ }
+
+ public void doNoting() {
+ }
+
+ public void doOneThing() {
+ System.out.println();
+ }
+
+ public void doMoreThings() {
+ something = 4;
+ doOneThing();
+ doOneThing();
+ }
+}
+
+public class EmptyClass {}
+
+public class TinyClass { int a; }
+
+public class SmallClass { int a; String b; }
+
+public class AnonymousClasses {
+ EmptyClass emptyAnonymous = new EmptyClass() {};
+ TinyClass tinyAnonymous = new TinyClass() {
+ String b;
+ };
+ Object o = new SmallClass() {
+ int a;
+
+ int getA() {
+ return a;
+ }
+ };
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum { A; }
+
+public enum SmallEnum {
+ VALUE(0);
+ SmallEnum(int val) {
+ };
+}
+
+public enum EnumConstants {
+ EMPTY {},
+ TINY {
+ int getVal() {
+ return 2;
+ }
+ },
+ SMALL {
+ int val = 3;
+
+ int getVal() {
+ return 3;
+ }
+ };
+ int getVal() {
+ return 1;
+ }
+}
+
+public @interface EmptyInterface {
+}
+
+public @interface TinyInterface {
+ void run();
+}
+
+public @interface SmallInteface {
+ int toA();
+
+ String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/G_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/G_out.java
new file mode 100644
index 0000000..fc1e78c
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/G_out.java
@@ -0,0 +1,121 @@
+class Example {
+ public void example() {
+ for (int i = 0; i < 10; i++) {
+ }
+ int a = 10;
+ while (a-- > 0) {
+ System.out.println(a);
+ }
+ do {
+ a += 2;
+ System.out.println(a);
+ } while (a < 50);
+ }
+}
+
+class Example {
+ public String example(int a) {
+ if (a < 0) { throw new IllegalArgumentException(); }
+ if (a == 0) { return null; }
+ if (false) {}
+ if (a % 3 == 0) { System.out.println("fizz"); }
+ if (a % 5 == 0) {
+ System.out.println("buzz");
+ return "";
+ }
+ return Integer.toString(a);
+ }
+}
+
+class Example {
+ Runnable emptyLambda = () -> {};
+ Runnable emptyLambda2 = () -> {};
+ Runnable tinyLambda = () -> { doSomething(); };
+ Runnable smallLambda = () -> { doFirstThing(); doSecondThing(); };
+}
+
+class Example {
+ static {}
+
+ void foo() {
+ if (true) {} else {}
+ synchronized (this) {}
+ try {} finally {}
+
+ labeled: {}
+ }
+}
+
+public class Example {
+ private int something;
+
+ public int getSomething() { return something; }
+
+ public void setSomehing(int something) { this.something = something; }
+
+ public void doNoting() {}
+
+ public void doOneThing() { System.out.println(); }
+
+ public void doMoreThings() { something = 4; doOneThing(); doOneThing(); }
+}
+
+public class EmptyClass {
+}
+
+public class TinyClass {
+ int a;
+}
+
+public class SmallClass {
+ int a;
+ String b;
+}
+
+public class AnonymousClasses {
+ EmptyClass emptyAnonymous = new EmptyClass() {
+ };
+ TinyClass tinyAnonymous = new TinyClass() {
+ String b;
+ };
+ Object o = new SmallClass() {
+ int a;
+
+ int getA() { return a; }
+ };
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum { A; }
+
+public enum SmallEnum {
+ VALUE(0);
+ SmallEnum(int val) {};
+}
+
+public enum EnumConstants {
+ EMPTY {
+ },
+ TINY {
+ int getVal() { return 2; }
+ },
+ SMALL {
+ int val = 3;
+
+ int getVal() { return 3; }
+ };
+ int getVal() { return 1; }
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface {
+ void run();
+}
+
+public @interface SmallInteface {
+ int toA();
+
+ String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/H_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/H_out.java
new file mode 100644
index 0000000..9eba7cd
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/H_out.java
@@ -0,0 +1,109 @@
+class Example {
+ public void example() {
+ for (int i = 0; i < 10; i++) {
+ }
+ int a = 10;
+ while (a-- > 0) { System.out.println(a); }
+ do {
+ a += 2;
+ System.out.println(a);
+ } while (a < 50);
+ }
+}
+
+class Example {
+ public String example(int a) {
+ if (a < 0) {
+ throw new IllegalArgumentException();
+ }
+ if (a == 0) { return null; }
+ if (false) {}
+ if (a % 3 == 0) {
+ System.out.println("fizz");
+ }
+ if (a % 5 == 0) { System.out.println("buzz"); return ""; }
+ return Integer.toString(a);
+ }
+}
+
+class Example {
+ Runnable emptyLambda = () -> {};
+ Runnable emptyLambda2 = () -> {
+ };
+ Runnable tinyLambda = () -> { doSomething(); };
+ Runnable smallLambda = () -> { doFirstThing(); doSecondThing(); };
+}
+
+class Example {
+ static {
+ }
+
+ void foo() {
+ if (true) {
+ } else {
+ }
+ synchronized (this) {
+ }
+ try {
+ } finally {
+ }
+
+ labeled: {
+ }
+ }
+}
+
+public class Example {
+ private int something;
+
+ public int getSomething() { return something; }
+
+ public void setSomehing(int something) { this.something = something; }
+
+ public void doNoting() {}
+
+ public void doOneThing() {
+ System.out.println();
+ }
+
+ public void doMoreThings() { something = 4; doOneThing(); doOneThing(); }
+}
+
+public class EmptyClass {}
+
+public class TinyClass {
+ int a;
+}
+
+public class SmallClass { int a; String b; }
+
+public class AnonymousClasses {
+ EmptyClass emptyAnonymous = new EmptyClass() {
+ };
+ TinyClass tinyAnonymous = new TinyClass() { String b; };
+ Object o = new SmallClass() { int a; int getA() { return a; } };
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum {
+ A;
+}
+
+public enum SmallEnum { VALUE(0); SmallEnum(int val) {}; }
+
+public enum EnumConstants {
+ EMPTY {
+ },
+ TINY { int getVal() { return 2; } },
+ SMALL { int val = 3; int getVal() { return 3; } };
+ int getVal() { return 1; }
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface {
+ void run();
+}
+
+public @interface SmallInteface { int toA(); String toB(); }
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/I_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/I_out.java
new file mode 100644
index 0000000..82d5839
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/I_out.java
@@ -0,0 +1,125 @@
+class Example {
+ public void example() {
+ for (int i = 0; i < 10; i++) {}
+ int a = 10;
+ while (a-- > 0) { System.out.println(a); }
+ do {
+ a += 2;
+ System.out.println(a);
+ } while (a < 50);
+ }
+}
+
+class Example {
+ public String example(int a) {
+ if (a < 0) {
+ throw new IllegalArgumentException();
+ }
+ if (a == 0) { return null; }
+ if (false) {}
+ if (a % 3 == 0) {
+ System.out.println("fizz");
+ }
+ if (a % 5 == 0) {
+ System.out.println("buzz");
+ return "";
+ }
+ return Integer.toString(a);
+ }
+}
+
+class Example {
+ Runnable emptyLambda = () -> {};
+ Runnable emptyLambda2 = () -> {};
+ Runnable tinyLambda = () -> {
+ doSomething();
+ };
+ Runnable smallLambda = () -> {
+ doFirstThing();
+ doSecondThing();
+ };
+}
+
+class Example {
+ static {}
+
+ void foo() {
+ if (true) {} else {}
+ synchronized (this) {}
+ try {} finally {}
+
+ labeled: {}
+ }
+}
+
+public class Example {
+ private int something;
+
+ public int getSomething() {
+ return something;
+ }
+
+ public void setSomehing(int something) {
+ this.something = something;
+ }
+
+ public void doNoting() {}
+
+ public void doOneThing() {
+ System.out.println();
+ }
+
+ public void doMoreThings() {
+ something = 4;
+ doOneThing();
+ doOneThing();
+ }
+}
+
+public class EmptyClass {}
+
+public class TinyClass { int a; }
+
+public class SmallClass { int a; String b; }
+
+public class AnonymousClasses {
+ EmptyClass emptyAnonymous = new EmptyClass() {};
+ TinyClass tinyAnonymous = new TinyClass() {
+ String b;
+ };
+ Object o = new SmallClass() {
+ int a;
+
+ int getA() { return a; }
+ };
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum { A; }
+
+public enum SmallEnum {
+ VALUE(0);
+ SmallEnum(int val) {};
+}
+
+public enum EnumConstants {
+ EMPTY {},
+ TINY { int getVal() { return 2; } },
+ SMALL {
+ int val = 3;
+
+ int getVal() { return 3; }
+ };
+ int getVal() { return 1; }
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface { void run(); }
+
+public @interface SmallInteface {
+ int toA();
+
+ String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_in.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_in.java
new file mode 100644
index 0000000..41d96d0
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_in.java
@@ -0,0 +1,30 @@
+class Example {
+
+ void method1() {
+ int a;
+ }
+
+ void method2() {
+
+ int a;
+
+
+ }
+
+ void method3() {
+ int a; //
+ }
+
+ void method4() {
+ int a; /* */
+ }
+
+ void method5() {
+ /* */ int a;
+ }
+
+ void method6() { int a; /* */ } /* */
+
+ void method7() { /* */ int a; } /* */
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_out.java
new file mode 100644
index 0000000..2a7ae61
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_out.java
@@ -0,0 +1,27 @@
+class Example {
+
+ void method1() { int a; }
+
+ void method2() {
+
+ int a;
+
+ }
+
+ void method3() {
+ int a; //
+ }
+
+ void method4() {
+ int a; /* */
+ }
+
+ void method5() {
+ /* */ int a;
+ }
+
+ void method6() { int a; /* */ } /* */
+
+ void method7() { /* */ int a; } /* */
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/in.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/in.java
new file mode 100644
index 0000000..bde96a4
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/in.java
@@ -0,0 +1,93 @@
+class Example{
+ public void example() {
+ for (int i = 0; i < 10; i++) {
+ }
+ int a = 10;
+ while (a-- > 0) { System.out.println(a); }
+ do { a += 2;
+ System.out.println(a); } while(a < 50);
+ }
+}
+
+
+class Example {
+ public String example(int a) {
+ if (a < 0) {
+ throw new IllegalArgumentException(); }
+ if (a == 0) { return null; }
+ if (false) {}
+ if (a % 3 == 0) {
+ System.out.println("fizz"); }
+ if (a % 5 == 0) { System.out.println("buzz"); return ""; }
+ return Integer.toString(a);
+ }
+}
+
+
+class Example {
+ Runnable emptyLambda = () -> {};
+ Runnable emptyLambda2 = () -> {
+ };
+ Runnable tinyLambda = () -> { doSomething(); };
+ Runnable smallLambda = () -> { doFirstThing(); doSecondThing(); };
+}
+
+
+class Example {
+ static {
+ }
+
+ void foo() {
+ if (true) {} else {}
+ synchronized(this) {}
+ try {} finally {}
+
+ labeled:{}
+ }
+}
+
+
+public class Example {
+ private int something;
+ public int getSomething() { return something; }
+ public void setSomehing(int something) { this.something = something; }
+ public void doNoting() {}
+ public void doOneThing() { System.out.println();
+ }
+ public void doMoreThings() { something = 4; doOneThing(); doOneThing(); }
+}
+
+
+public class EmptyClass{}
+public class TinyClass{
+ int a; }
+public class SmallClass{ int a; String b; }
+
+
+public class AnonymousClasses {
+ EmptyClass emptyAnonymous = new EmptyClass() {
+ };
+ TinyClass tinyAnonymous = new TinyClass() { String b; };
+ Object o = new SmallClass() { int a; int getA() { return a; } };
+}
+
+
+public enum EmptyEnum {}
+public enum TinyEnum{ A;
+}
+public enum SmallEnum{ VALUE(0); SmallEnum(int val) {}; }
+
+
+public enum EnumConstants {
+ EMPTY {
+ },
+ TINY { int getVal() { return 2; }},
+ SMALL { int val = 3; int getVal() { return 3; }};
+ int getVal() { return 1; }
+}
+
+
+public @interface EmptyInterface {}
+public @interface TinyInterface {
+ void run(); }
+public @interface SmallInteface { int toA(); String toB(); }
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test496/A_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test496/A_out.java
index 7b6cead..19532de 100644
--- a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test496/A_out.java
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test496/A_out.java
@@ -1,7 +1,8 @@
public class A {
void doX() {
- if (1 > 0) { return; //
+ if (1 > 0) {
+ return; //
}
return;
}
diff --git a/org.eclipse.jdt.core/.options b/org.eclipse.jdt.core/.options
index a90286e..d558214 100644
--- a/org.eclipse.jdt.core/.options
+++ b/org.eclipse.jdt.core/.options
@@ -1,5 +1,5 @@
# Turn on debug tracing for org.eclipse.jdt.core plugin
-org.eclipse.jdt.core/debug=true
+org.eclipse.jdt.core/debug=false
# Reports buffer manager activity
org.eclipse.jdt.core/debug/buffermanager=false
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
index 7cdf9dc..da4229a 100644
--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -16,9 +16,9 @@
org.eclipse.jdt.core.formatter,
org.eclipse.jdt.core.index,
org.eclipse.jdt.core.jdom,
+ org.eclipse.jdt.core.provisional;x-friends:="org.eclipse.jdt.debug.ui,org.eclipse.jdt.launching,org.eclipse.jdt.ui",
org.eclipse.jdt.core.search,
org.eclipse.jdt.core.util,
- org.eclipse.jdt.core.provisional;x-friends:="org.eclipse.jdt.debug.ui,org.eclipse.jdt.launching",
org.eclipse.jdt.internal.codeassist;x-internal:=true,
org.eclipse.jdt.internal.codeassist.complete;x-internal:=true,
org.eclipse.jdt.internal.codeassist.impl;x-internal:=true,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
index d093225..8498b31 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
@@ -79,7 +79,9 @@
private static final int REPORTED_POTENTIAL_LEAK = 32;
// a location independent definitive problem has been reported against this resource:
private static final int REPORTED_DEFINITIVE_LEAK = 64;
-
+ // a local declarations that acts as the element variable of a foreach loop (should never suggest to use t-w-r):
+ private static final int FOREACH_ELEMENT_VAR = 128;
+
public static boolean TEST_372319 = false; // see https://bugs.eclipse.org/372319
/**
@@ -449,9 +451,9 @@
if (rhsTrackVar.originalBinding != null)
local.closeTracker = rhsTrackVar; // a.: let fresh LHS share it
if (rhsTrackVar.currentAssignment == location) {
- // pre-set tracker from lhs - passed from outside?
+ // pre-set tracker from lhs - passed from outside (or foreach)?
// now it's a fresh resource
- rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE);
+ rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR);
}
} else {
if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression) {
@@ -484,7 +486,7 @@
}
}
// re-assigning from a fresh value, mark as not-closed again:
- if ((previousTracker.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE)) == 0
+ if ((previousTracker.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR)) == 0
&& flowInfo.hasNullInfoFor(previousTracker.binding)) // avoid spilling info into a branch that doesn't see the corresponding resource
flowInfo.markAsDefinitelyNull(previousTracker.binding);
local.closeTracker = analyseCloseableExpression(flowInfo, flowContext, local, location, rhs, previousTracker);
@@ -494,7 +496,7 @@
if (rhsTrackVar != null) {
local.closeTracker = rhsTrackVar;
// a fresh resource, mark as not-closed:
- if ((rhsTrackVar.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE)) == 0)
+ if ((rhsTrackVar.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR)) == 0)
flowInfo.markAsDefinitelyNull(rhsTrackVar.binding);
// TODO(stephan): this might be useful, but I could not find a test case for it:
// if (flowContext.initsOnFinally != null)
@@ -753,6 +755,12 @@
return flowInfo;
}
+ public static void markForeachElementVar(LocalDeclaration local) {
+ if (local.binding != null && local.binding.closeTracker != null) {
+ local.binding.closeTracker.globalClosingState |= FOREACH_ELEMENT_VAR;
+ }
+ }
+
/**
* Iterator for a set of FakedTrackingVariable, which dispenses the elements
* according to the priorities defined by enum {@link Stage}.
@@ -987,7 +995,7 @@
}
public void reportExplicitClosing(ProblemReporter problemReporter) {
- if ((this.globalClosingState & (OWNED_BY_OUTSIDE|REPORTED_EXPLICIT_CLOSE)) == 0) { // can't use t-w-r for OWNED_BY_OUTSIDE
+ if ((this.globalClosingState & (OWNED_BY_OUTSIDE|REPORTED_EXPLICIT_CLOSE|FOREACH_ELEMENT_VAR)) == 0) { // can't use t-w-r for OWNED_BY_OUTSIDE
this.globalClosingState |= REPORTED_EXPLICIT_CLOSE;
problemReporter.explicitlyClosedAutoCloseable(this);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
index edbc221..fe438b0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
@@ -99,7 +99,7 @@
int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
// process the element variable and collection
- flowInfo = this.elementVariable.analyseCode(this.scope, flowContext, flowInfo);
+ flowInfo = this.elementVariable.analyseCode(this.scope, flowContext, flowInfo);
FlowInfo condInfo = this.collection.analyseCode(this.scope, flowContext, flowInfo.copy());
this.collection.checkNPE(currentScope, flowContext, condInfo.copy(), 1);
LocalVariableBinding elementVarBinding = this.elementVariable.binding;
@@ -131,6 +131,11 @@
if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) {
actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalCopy();
+ if (this.action instanceof Block) {
+ FakedTrackingVariable.markForeachElementVar(this.elementVariable);
+ // action.analyseCode() missed the following check due to identical scopes of ForeachStatement and Block:
+ this.scope.checkUnclosedCloseables(actionInfo, loopingContext, null, null);
+ }
}
// code generation can be optimized when no need to continue in the loop
@@ -147,6 +152,9 @@
}
} else {
exitBranch = condInfo.initsWhenFalse();
+ if (this.action instanceof Block && !this.action.isEmptyBlock()) {
+ this.scope.checkUnclosedCloseables(actionInfo, loopingContext, null, null);
+ }
}
// we need the variable to iterate the collection even if the
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
index 48e4112..422d230 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
@@ -174,10 +174,9 @@
case ClassFileConstants.MAJOR_VERSION_1_1:
return ((long)ClassFileConstants.MAJOR_VERSION_1_1 << 16) + ClassFileConstants.MINOR_VERSION_3;
default:
- if (major <= MAJOR_LATEST_VERSION)
- return ((long)major << 16) + ClassFileConstants.MINOR_VERSION_0;
+ major = Math.min(major, MAJOR_LATEST_VERSION);
+ return ((long)major << 16) + ClassFileConstants.MINOR_VERSION_0;
}
- return 0;
}
/*
* cldc1.1 is 45.3, but we modify it to be different from JDK1_1.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java
index e602d24..b7b81f4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java
@@ -16,6 +16,7 @@
import java.util.function.Predicate;
import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
+import org.eclipse.jdt.internal.compiler.util.SimpleSetOfCharArray;
/**
* A module aware name environment
@@ -107,6 +108,18 @@
/** Answer a type identified by the given names. moduleName may be one of the special names from ModuleBinding (ANY, ANY_NAMED, UNNAMED). */
NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, char[] moduleName);
char[][] getModulesDeclaringPackage(char[][] parentPackageName, char[] name, char[] moduleName);
+ default char[][] getUniqueModulesDeclaringPackage(char[][] parentPackageName, char[] name, char[] moduleName) {
+ char[][] allNames = getModulesDeclaringPackage(parentPackageName, name, moduleName);
+ if (allNames != null && allNames.length > 1) {
+ SimpleSetOfCharArray set = new SimpleSetOfCharArray(allNames.length);
+ for (char[] oneName : allNames)
+ set.add(oneName);
+ allNames = new char[set.elementSize][];
+ set.asArray(allNames);
+ }
+ return allNames;
+ }
+
/**
* Answer whether the given package (within the given module) contains any compilation unit.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index 08845d0..802ab27 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -831,6 +831,9 @@
return 0;
}
public static long versionToJdkLevel(String versionID) {
+ return versionToJdkLevel(versionID, true);
+ }
+ public static long versionToJdkLevel(String versionID, boolean supportUnreleased) {
String version = versionID;
// verification is optimized for all versions with same length and same "1." prefix
if (version != null && version.length() > 0) {
@@ -866,10 +869,13 @@
version = version.substring(0, index);
}
int major = Integer.parseInt(version) + ClassFileConstants.MAJOR_VERSION_0;
- if (major <= ClassFileConstants.MAJOR_LATEST_VERSION) {
- long jdkLevel = ((long) major << 16) + ClassFileConstants.MINOR_VERSION_0;
- return jdkLevel;
+ if (major > ClassFileConstants.MAJOR_LATEST_VERSION) {
+ if (supportUnreleased)
+ major = ClassFileConstants.MAJOR_LATEST_VERSION;
+ else
+ return 0; // unknown
}
+ return ((long) major << 16) + ClassFileConstants.MINOR_VERSION_0;
} catch (NumberFormatException e) {
// do nothing and return 0 at the end
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
index 6ea3c62..ea2b900 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * 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
@@ -125,8 +125,8 @@
moduleDecl.createScope(this);
moduleDecl.checkAndSetModifiers();
}
- } else if (this.environment.module != this.environment.UnNamedModule) {
- problemReporter().unnamedPackageInNamedModule(this.environment.module);
+ } else if (module() != this.environment.UnNamedModule) {
+ problemReporter().unnamedPackageInNamedModule(module());
}
} else {
if ((this.fPackage = this.environment.createPackage(this.currentPackageName)) == null) {
@@ -678,6 +678,18 @@
return this.captureID++;
}
+@Override
+public ModuleBinding module() {
+ if (!this.referenceContext.isModuleInfo() &&
+ this.referenceContext.types == null &&
+ this.referenceContext.currentPackage == null &&
+ this.referenceContext.imports == null) {
+ this.environment = this.environment.UnNamedModule.environment;
+ return this.environment.UnNamedModule;
+ }
+ return super.module();
+}
+
/* Answer the problem reporter to use for raising new problems.
*
* Note that as a side-effect, this updates the current reference context
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 90f4431..7c37358 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -300,6 +300,8 @@
ReferenceBinding candidate = null;
for (NameEnvironmentAnswer answer : answers) {
if (answer == null) continue;
+ if (candidate != null && candidate.problemId() == ProblemReasons.Ambiguous)
+ return candidate; // saw enough
ModuleBinding answerModule = answer.moduleBinding != null ? answer.moduleBinding : this.UnNamedModule;
PackageBinding answerPackage = packageBinding;
@@ -343,8 +345,6 @@
continue;
}
candidate = combine(candidate, answerPackage.getType0(name), clientModule);
- if (candidate != null && candidate.problemId() == ProblemReasons.Ambiguous)
- return candidate; // saw enough
}
return candidate;
}
@@ -729,7 +729,7 @@
if (packageBinding == null || packageBinding == TheNotFoundPackage) {
if (this.useModuleSystem) {
if (this.module.isUnnamed()) {
- char[][] declaringModules = ((IModuleAwareNameEnvironment) this.nameEnvironment).getModulesDeclaringPackage(null, constantPoolName[0], ModuleBinding.ANY);
+ char[][] declaringModules = ((IModuleAwareNameEnvironment) this.nameEnvironment).getUniqueModulesDeclaringPackage(null, constantPoolName[0], ModuleBinding.ANY);
if (declaringModules != null) {
for (char[] mod : declaringModules) {
ModuleBinding declaringModule = this.root.getModule(mod);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
index 7cf8b0e..d6117ed 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
@@ -18,9 +18,12 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jdt.core.compiler.CharOperation;
@@ -535,12 +538,13 @@
}
PackageBinding binding = null;
+ char[][] declaringModuleNames = null;
boolean packageMayBeIncomplete = !considerRequiredModules;
if (this.environment.useModuleSystem) {
IModuleAwareNameEnvironment moduleEnv = (IModuleAwareNameEnvironment) this.environment.nameEnvironment;
- char[][] declaringModuleNames = moduleEnv.getModulesDeclaringPackage(parentName, name, nameForLookup());
+ declaringModuleNames = moduleEnv.getUniqueModulesDeclaringPackage(parentName, name, nameForLookup());
if (declaringModuleNames != null) {
- if (!this.isUnnamed() && CharOperation.containsEqual(declaringModuleNames, this.moduleName)) {
+ if (CharOperation.containsEqual(declaringModuleNames, this.moduleName)) {
// declared here, not yet known, so create it now:
binding = new PackageBinding(subPkgCompoundName, parent, this.environment, this);
} else if (considerRequiredModules) {
@@ -571,8 +575,8 @@
}
// enrich with split-siblings from visible modules:
- if (!isUnnamed() && considerRequiredModules) {
- binding = combineWithPackagesFromRequired(binding, subPkgCompoundName);
+ if (considerRequiredModules) {
+ binding = combineWithPackagesFromOtherRelevantModules(binding, subPkgCompoundName, declaringModuleNames);
}
if (binding == null || !binding.isValidBinding()) {
if (parent != null && !packageMayBeIncomplete) // don't remember package that may still lack some siblings
@@ -596,6 +600,9 @@
* </p>
*/
public PackageBinding getVisiblePackage(char[][] qualifiedPackageName) {
+ return getVisiblePackage(qualifiedPackageName, true);
+ }
+ PackageBinding getVisiblePackage(char[][] qualifiedPackageName, boolean considerRequiredModules) {
if (qualifiedPackageName == null || qualifiedPackageName.length == 0) {
return this.environment.defaultPackage;
}
@@ -606,7 +613,7 @@
// check each sub package
for (int i = 1; i < qualifiedPackageName.length; i++) {
- PackageBinding binding = getVisiblePackage(parent, qualifiedPackageName[i], true);
+ PackageBinding binding = getVisiblePackage(parent, qualifiedPackageName[i], considerRequiredModules);
if (binding == null || binding == LookupEnvironment.TheNotFoundPackage) {
return null;
}
@@ -653,19 +660,12 @@
if (packageBinding.isDeclaredIn(this)) {
char[] packageName = packageBinding.readableName();
if (checkForSplit && this.environment.useModuleSystem) {
+ char[][] declaringModuleNames = null;
if (isUnnamed()) {
IModuleAwareNameEnvironment moduleEnv = (IModuleAwareNameEnvironment) this.environment.nameEnvironment;
- char[][] declaringModuleNames = moduleEnv.getModulesDeclaringPackage(null, packageName, ANY);
- if (declaringModuleNames != null) {
- for (int i = 0; i < declaringModuleNames.length; i++) {
- ModuleBinding otherModule = this.environment.getModule(declaringModuleNames[i]);
- if (otherModule != null && !otherModule.isPackageLookupActive)
- packageBinding = SplitPackageBinding.combine(otherModule.getVisiblePackage(packageBinding.compoundName), packageBinding, this);
- }
- }
- } else {
- packageBinding = combineWithPackagesFromRequired(packageBinding, packageBinding.compoundName);
+ declaringModuleNames = moduleEnv.getUniqueModulesDeclaringPackage(null, packageName, ANY);
}
+ packageBinding = combineWithPackagesFromOtherRelevantModules(packageBinding, packageBinding.compoundName, declaringModuleNames);
}
this.declaredPackages.put(packageName, packageBinding);
if (packageBinding.parent == null) {
@@ -675,19 +675,40 @@
return packageBinding;
}
- private PackageBinding combineWithPackagesFromRequired(PackageBinding currentBinding, char[][] compoundName) {
+ private PackageBinding combineWithPackagesFromOtherRelevantModules(PackageBinding currentBinding, char[][] compoundName, char[][] declaringModuleNames) {
boolean save = this.isPackageLookupActive;
this.isPackageLookupActive = true;
try {
- for (ModuleBinding moduleBinding : getAllRequiredModules())
- if (!moduleBinding.isPackageLookupActive)
- currentBinding = SplitPackageBinding.combine(moduleBinding.getVisiblePackage(compoundName), currentBinding, this);
+ char[] singleName = compoundName[compoundName.length-1];
+ PackageBinding parent = currentBinding != null ? currentBinding.parent : null;
+ for (ModuleBinding moduleBinding : otherRelevantModules(declaringModuleNames)) {
+ if (!moduleBinding.isPackageLookupActive) {
+ PackageBinding nextBinding = parent != null
+ ? moduleBinding.getVisiblePackage(parent, singleName, false)
+ : moduleBinding.getVisiblePackage(compoundName, false);
+ currentBinding = SplitPackageBinding.combine(nextBinding, currentBinding, this);
+ }
+ }
return currentBinding;
} finally {
this.isPackageLookupActive = save;
}
}
+ List<ModuleBinding> otherRelevantModules(char[][] declaringModuleNames) {
+ if (isUnnamed() && declaringModuleNames != null) {
+ // unnamed module reads all named modules,
+ // so all modules declaring the given package are relevant:
+ return Arrays.stream(declaringModuleNames)
+ .filter(modName -> modName != UNNAMED)
+ .map(modName -> this.environment.getModule(modName))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ } else {
+ return Arrays.asList(getAllRequiredModules());
+ }
+ }
+
/**
* Check if the given package is accessible by this module. True when the package is declared in
* this module or exported by some required module to this module.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index da4f2cf..28ef21f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -751,7 +751,7 @@
} while (scope != null);
return (CompilationUnitScope) lastScope;
}
- public final ModuleBinding module() {
+ public ModuleBinding module() {
return environment().module;
}
public boolean isLambdaScope() {
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
index 7716e2a..e663811 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
@@ -917,6 +917,7 @@
* @since 3.1
* @deprecated Use {@link #FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT} and {@link #FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT}
*/
+ @Deprecated
public final static String FORMATTER_COMMENT_CLEAR_BLANK_LINES = "org.eclipse.jdt.core.formatter.comment.clear_blank_lines"; //$NON-NLS-1$
/**
@@ -958,6 +959,7 @@
* @deprecated Use multiple settings for each kind of comments. See {@link #FORMATTER_COMMENT_FORMAT_BLOCK_COMMENT},
* {@link #FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT} and {@link #FORMATTER_COMMENT_FORMAT_LINE_COMMENT}.
*/
+ @Deprecated
public final static String FORMATTER_COMMENT_FORMAT = "org.eclipse.jdt.core.formatter.comment.format_comments"; //$NON-NLS-1$
/**
@@ -1670,6 +1672,7 @@
* {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE}
* {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PARAMETER}
*/
+ @Deprecated
public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation";//$NON-NLS-1$
/**
@@ -1689,6 +1692,7 @@
* {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE}
* {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE}
*/
+ @Deprecated
public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation_on_member";//$NON-NLS-1$
/**
@@ -1902,7 +1906,9 @@
* @see JavaCore#INSERT
* @see JavaCore#DO_NOT_INSERT
* @since 3.2
+ * @deprecated Use {@link #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE} instead.
*/
+ @Deprecated
public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_annotation_declaration"; //$NON-NLS-1$
/**
* <pre>
@@ -1914,7 +1920,9 @@
* @see JavaCore#INSERT
* @see JavaCore#DO_NOT_INSERT
* @since 3.0
+ * @deprecated Use {@link #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE} instead.
*/
+ @Deprecated
public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_anonymous_type_declaration"; //$NON-NLS-1$
/**
* <pre>
@@ -1926,7 +1934,12 @@
* @see JavaCore#INSERT
* @see JavaCore#DO_NOT_INSERT
* @since 3.0
+ * @deprecated Use {@link #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE},
+ * {@link #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE},
+ * {@link #FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE}, and
+ * {@link #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE} instead.
*/
+ @Deprecated
public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_block"; //$NON-NLS-1$
/**
* <pre>
@@ -1938,7 +1951,9 @@
* @see JavaCore#INSERT
* @see JavaCore#DO_NOT_INSERT
* @since 3.1
+ * @deprecated Use {@link #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE} instead.
*/
+ @Deprecated
public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_enum_constant"; //$NON-NLS-1$
/**
* <pre>
@@ -1950,7 +1965,9 @@
* @see JavaCore#INSERT
* @see JavaCore#DO_NOT_INSERT
* @since 3.1
+ * @deprecated Use {@link #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE} instead.
*/
+ @Deprecated
public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_enum_declaration"; //$NON-NLS-1$
/**
* <pre>
@@ -1962,7 +1979,9 @@
* @see JavaCore#INSERT
* @see JavaCore#DO_NOT_INSERT
* @since 3.0
+ * @deprecated Use {@link #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE} instead.
*/
+ @Deprecated
public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_method_body"; //$NON-NLS-1$
/**
* <pre>
@@ -1974,8 +1993,11 @@
* @see JavaCore#INSERT
* @see JavaCore#DO_NOT_INSERT
* @since 3.0
+ * @deprecated Use {@link #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE} instead.
*/
+ @Deprecated
public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_type_declaration"; //$NON-NLS-1$
+
/**
* <pre>
* FORMATTER / Option to insert a space after and in wilcard
@@ -3939,13 +3961,15 @@
public static final String FORMATTER_KEEP_EMPTY_ARRAY_INITIALIZER_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_empty_array_initializer_on_one_line"; //$NON-NLS-1$
/**
* <pre>
- * FORMATTER / Option to keep guardian clause on one line
+ * FORMATTER / Option to keep guardian clause on one line, in addition to the
+ * #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE option
* - option id: "org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line"
* - possible values: { TRUE, FALSE }
* - default: FALSE
* </pre>
* @see #TRUE
* @see #FALSE
+ * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
* @since 3.0
*/
public static final String FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.format_guardian_clause_on_one_line"; //$NON-NLS-1$
@@ -4013,6 +4037,180 @@
/**
* <pre>
+ * FORMATTER / Option to control when a loop body block should be kept on one line
+ * - option id: "org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line"
+ * - possible values: { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+ * ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+ * - default: ONE_LINE_NEVER
+ * </pre>
+ * @see #ONE_LINE_NEVER
+ * @see #ONE_LINE_IF_EMPTY
+ * @see #ONE_LINE_IF_SINGLE_ITEM
+ * @see #ONE_LINE_ALWAYS
+ * @see #ONE_LINE_PRESERVE
+ * @since 3.16
+ */
+ public static final String FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_loop_body_block_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to control when an if-then statement body block should be kept on one line
+ * - option id: "org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line"
+ * - possible values: { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+ * ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+ * - default: ONE_LINE_NEVER
+ * </pre>
+ * @see #ONE_LINE_NEVER
+ * @see #ONE_LINE_IF_EMPTY
+ * @see #ONE_LINE_IF_SINGLE_ITEM
+ * @see #ONE_LINE_ALWAYS
+ * @see #ONE_LINE_PRESERVE
+ * @see #FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE for a special case
+ * @since 3.16
+ */
+ public static final String FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_if_then_body_block_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to control when a code block other than if-then and loop body should
+ * be kept on one line
+ * - option id: "org.eclipse.jdt.core.formatter.keep_code_block_on_one_line"
+ * - possible values: { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY }
+ * - default: ONE_LINE_NEVER
+ * </pre>
+ * @see #ONE_LINE_NEVER
+ * @see #ONE_LINE_IF_EMPTY
+ * @since 3.16
+ */
+ public static final String FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_code_block_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to control when a method body should be kept on one line
+ * - option id: "org.eclipse.jdt.core.formatter.keep_method_body_on_one_line"
+ * - possible values: { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+ * ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+ * - default: ONE_LINE_NEVER
+ * </pre>
+ * @see #ONE_LINE_NEVER
+ * @see #ONE_LINE_IF_EMPTY
+ * @see #ONE_LINE_IF_SINGLE_ITEM
+ * @see #ONE_LINE_ALWAYS
+ * @see #ONE_LINE_PRESERVE
+ * @since 3.16
+ */
+ public static final String FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_method_body_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to control when a lambda body should be kept on one line
+ * - option id: "org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line"
+ * - possible values: { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+ * ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+ * - default: ONE_LINE_NEVER
+ * </pre>
+ * @see #ONE_LINE_NEVER
+ * @see #ONE_LINE_IF_EMPTY
+ * @see #ONE_LINE_IF_SINGLE_ITEM
+ * @see #ONE_LINE_ALWAYS
+ * @see #ONE_LINE_PRESERVE
+ * @since 3.16
+ */
+ public static final String FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_lambda_body_block_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to always keep simple getters and setters on one line, in addition to the
+ * #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE option
+ * - option id: "org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+ * @since 3.16
+ */
+ public static final String FORMATTER_KEEP_SIMPLE_GETTER_SETTER_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_simple_getter_setter_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to control when a type declaration should be kept on one line
+ * - option id: "org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line"
+ * - possible values: { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+ * ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+ * - default: ONE_LINE_NEVER
+ * </pre>
+ * @see #ONE_LINE_NEVER
+ * @see #ONE_LINE_IF_EMPTY
+ * @see #ONE_LINE_IF_SINGLE_ITEM
+ * @see #ONE_LINE_ALWAYS
+ * @see #ONE_LINE_PRESERVE
+ * @since 3.16
+ * @since 3.0
+ */
+ public static final String FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_type_declaration_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to control when an anonymous type declaration should be kept on one line
+ * - option id: "org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line"
+ * - possible values: { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+ * ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+ * - default: ONE_LINE_NEVER
+ * </pre>
+ * @see #ONE_LINE_NEVER
+ * @see #ONE_LINE_IF_EMPTY
+ * @see #ONE_LINE_IF_SINGLE_ITEM
+ * @see #ONE_LINE_ALWAYS
+ * @see #ONE_LINE_PRESERVE
+ * @since 3.16
+ */
+ public static final String FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_anonymous_type_declaration_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to control when an enum constant declaration body should be kept on one line
+ * - option id: "org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line"
+ * - possible values: { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+ * ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+ * - default: ONE_LINE_NEVER
+ * </pre>
+ * @see #ONE_LINE_NEVER
+ * @see #ONE_LINE_IF_EMPTY
+ * @see #ONE_LINE_IF_SINGLE_ITEM
+ * @see #ONE_LINE_ALWAYS
+ * @see #ONE_LINE_PRESERVE
+ * @since 3.16
+ */
+ public static final String FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_enum_constant_declaration_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to control when an enum declaration should be kept on one line
+ * - option id: "org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line"
+ * - possible values: { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+ * ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+ * - default: ONE_LINE_NEVER
+ * </pre>
+ * @see #ONE_LINE_NEVER
+ * @see #ONE_LINE_IF_EMPTY
+ * @see #ONE_LINE_IF_SINGLE_ITEM
+ * @see #ONE_LINE_ALWAYS
+ * @see #ONE_LINE_PRESERVE
+ * @since 3.16
+ */
+ public static final String FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_enum_declaration_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to control when an annotation declaration should be kept on one line
+ * - option id: "org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line"
+ * - possible values: { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+ * ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+ * - default: ONE_LINE_NEVER
+ * </pre>
+ * @see #ONE_LINE_NEVER
+ * @see #ONE_LINE_IF_EMPTY
+ * @see #ONE_LINE_IF_SINGLE_ITEM
+ * @see #ONE_LINE_ALWAYS
+ * @see #ONE_LINE_PRESERVE
+ * @since 3.16
+ */
+ public static final String FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_annotation_declaration_on_one_line"; //$NON-NLS-1$
+
+ /**
+ * <pre>
* FORMATTER / Option to specify the length of the page. Beyond this length, the formatter will try to split the code
* - option id: "org.eclipse.jdt.core.formatter.lineSplit"
* - possible values: "<n>", where n is zero or a positive integer
@@ -4439,6 +4637,92 @@
/**
* <pre>
+ * FORMATTER / Value to never keep braced code on one line.
+ * </pre>
+ * @see #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE
+ * @since 3.16
+ */
+ public static final String ONE_LINE_NEVER = "one_line_never"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to keep braced code on one line only if it's empty.
+ * </pre>
+ * @see #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE
+ * @since 3.16
+ */
+ public static final String ONE_LINE_IF_EMPTY = "one_line_if_empty"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to keep braced code on one line if it contains at most a single
+ * item.
+ * </pre>
+ * @see #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE
+ * @since 3.16
+ */
+ public static final String ONE_LINE_IF_SINGLE_ITEM = "one_line_if_single_item"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to always keep braced code on one line, as long as it doesn't
+ * exceed the line width limit.
+ * </pre>
+ * @see #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE
+ * @since 3.16
+ */
+ public static final String ONE_LINE_ALWAYS = "one_line_always"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to keep braced code on one line as long as it doesn't exceed the
+ * line width limit and it was already in one line in the original source.
+ * </pre>
+ * @see #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE
+ * @see #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE
+ * @since 3.16
+ */
+ public static final String ONE_LINE_PRESERVE = "one_line_preserve"; //$NON-NLS-1$
+
+ /**
+ * <pre>
* FORMATTER / Value to set an option to true.
* </pre>
* @since 3.0
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
index 744b097..c222422 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
@@ -414,6 +414,7 @@
LineBreaksPreparator breaksPreparator = new LineBreaksPreparator(this.tokenManager, this.workingOptions);
this.astRoot.accept(breaksPreparator);
breaksPreparator.finishUp();
+ this.astRoot.accept(new OneLineEnforcer(this.tokenManager, this.workingOptions));
}
private void prepareComments() {
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
index b4ae48f..4f8fce8 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
@@ -19,11 +19,14 @@
*******************************************************************************/
package org.eclipse.jdt.internal.formatter;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.function.Consumer;
-import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.jdt.internal.compiler.util.Util;
/**
@@ -246,13 +249,19 @@
public boolean insert_new_line_before_else_in_if_statement;
public boolean insert_new_line_before_finally_in_try_statement;
public boolean insert_new_line_before_while_in_do_statement;
- public boolean insert_new_line_in_empty_anonymous_type_declaration;
- public boolean insert_new_line_in_empty_block;
- public boolean insert_new_line_in_empty_annotation_declaration;
- public boolean insert_new_line_in_empty_enum_constant;
- public boolean insert_new_line_in_empty_enum_declaration;
- public boolean insert_new_line_in_empty_method_body;
- public boolean insert_new_line_in_empty_type_declaration;
+
+ public String keep_loop_body_block_on_one_line;
+ public String keep_if_then_body_block_on_one_line;
+ public String keep_code_block_on_one_line;
+ public String keep_lambda_body_block_on_one_line;
+ public String keep_method_body_on_one_line;
+ public String keep_type_declaration_on_one_line;
+ public String keep_anonymous_type_declaration_on_one_line;
+ public String keep_enum_declaration_on_one_line;
+ public String keep_enum_constant_declaration_on_one_line;
+ public String keep_annotation_declaration_on_one_line;
+ public boolean keep_simple_getter_setter_on_one_line;
+
public boolean insert_space_after_and_in_type_parameter;
public boolean insert_space_after_assignment_operator;
public boolean insert_space_after_at_in_annotation;
@@ -443,6 +452,13 @@
public int initial_indentation_level;
public String line_separator;
+ private final static List<String> KEEP_ON_ONE_LINE_VALUES = Arrays.asList(
+ DefaultCodeFormatterConstants.ONE_LINE_NEVER,
+ DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY,
+ DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM,
+ DefaultCodeFormatterConstants.ONE_LINE_ALWAYS,
+ DefaultCodeFormatterConstants.ONE_LINE_PRESERVE);
+
private DefaultCodeFormatterOptions() {
// cannot be instantiated
}
@@ -576,13 +592,17 @@
options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT, this.insert_new_line_before_else_in_if_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT, this.insert_new_line_before_finally_in_try_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT, this.insert_new_line_before_while_in_do_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
- options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION, this.insert_new_line_in_empty_anonymous_type_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
- options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, this.insert_new_line_in_empty_block? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
- options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION, this.insert_new_line_in_empty_annotation_declaration ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
- options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT, this.insert_new_line_in_empty_enum_constant? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
- options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION, this.insert_new_line_in_empty_enum_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
- options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY, this.insert_new_line_in_empty_method_body? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
- options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION, this.insert_new_line_in_empty_type_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE, this.keep_annotation_declaration_on_one_line);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE, this.keep_anonymous_type_declaration_on_one_line);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE, this.keep_if_then_body_block_on_one_line);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE, this.keep_lambda_body_block_on_one_line);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE, this.keep_loop_body_block_on_one_line);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE, this.keep_code_block_on_one_line);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE, this.keep_enum_constant_declaration_on_one_line);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE, this.keep_enum_declaration_on_one_line);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE, this.keep_method_body_on_one_line);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE, this.keep_type_declaration_on_one_line);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_SIMPLE_GETTER_SETTER_ON_ONE_LINE, this.keep_simple_getter_setter_on_one_line? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_LABEL, this.insert_new_line_after_label? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_AND_IN_TYPE_PARAMETER, this.insert_space_after_and_in_type_parameter? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR, this.insert_space_after_assignment_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
@@ -1521,34 +1541,31 @@
if (insertNewLineBeforeWhileInDoStatementOption != null) {
this.insert_new_line_before_while_in_do_statement = JavaCore.INSERT.equals(insertNewLineBeforeWhileInDoStatementOption);
}
- final Object insertNewLineInEmptyAnonymousTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION);
- if (insertNewLineInEmptyAnonymousTypeDeclarationOption != null) {
- this.insert_new_line_in_empty_anonymous_type_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyAnonymousTypeDeclarationOption);
- }
- final Object insertNewLineInEmptyBlockOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK);
- if (insertNewLineInEmptyBlockOption != null) {
- this.insert_new_line_in_empty_block = JavaCore.INSERT.equals(insertNewLineInEmptyBlockOption);
- }
- final Object insertNewLineInEmptyAnnotationDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION);
- if (insertNewLineInEmptyAnnotationDeclarationOption != null) {
- this.insert_new_line_in_empty_annotation_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyAnnotationDeclarationOption);
- }
- final Object insertNewLineInEmptyEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT);
- if (insertNewLineInEmptyEnumConstantOption != null) {
- this.insert_new_line_in_empty_enum_constant = JavaCore.INSERT.equals(insertNewLineInEmptyEnumConstantOption);
- }
- final Object insertNewLineInEmptyEnumDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION);
- if (insertNewLineInEmptyEnumDeclarationOption != null) {
- this.insert_new_line_in_empty_enum_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyEnumDeclarationOption);
- }
- final Object insertNewLineInEmptyMethodBodyOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY);
- if (insertNewLineInEmptyMethodBodyOption != null) {
- this.insert_new_line_in_empty_method_body = JavaCore.INSERT.equals(insertNewLineInEmptyMethodBodyOption);
- }
- final Object insertNewLineInEmptyTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION);
- if (insertNewLineInEmptyTypeDeclarationOption != null) {
- this.insert_new_line_in_empty_type_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyTypeDeclarationOption);
- }
+
+ setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+ v -> this.keep_annotation_declaration_on_one_line = v);
+ setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+ v -> this.keep_anonymous_type_declaration_on_one_line = v);
+ setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+ v -> this.keep_if_then_body_block_on_one_line = v);
+ setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+ v -> this.keep_loop_body_block_on_one_line = v);
+ setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+ v -> this.keep_lambda_body_block_on_one_line = v);
+ setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE,
+ Arrays.asList(DefaultCodeFormatterConstants.ONE_LINE_NEVER, DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY),
+ v -> this.keep_code_block_on_one_line = v);
+ setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+ v -> this.keep_enum_constant_declaration_on_one_line = v);
+ setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+ v -> this.keep_enum_declaration_on_one_line = v);
+ setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+ v -> this.keep_method_body_on_one_line = v);
+ setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+ v -> this.keep_type_declaration_on_one_line = v);
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_SIMPLE_GETTER_SETTER_ON_ONE_LINE, DefaultCodeFormatterConstants.TRUE,
+ v -> this.keep_simple_getter_setter_on_one_line = v);
+
final Object insertNewLineAfterLabelOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_LABEL);
if (insertNewLineAfterLabelOption != null) {
this.insert_new_line_after_label = JavaCore.INSERT.equals(insertNewLineAfterLabelOption);
@@ -2380,6 +2397,21 @@
return defaultValue;
}
+ private void setString(Map<String, String> settings, String key, List<String> allowedValues, Consumer<String> setter) {
+ Object value = settings.get(key);
+ if (value != null) {
+ if (!allowedValues.contains(value))
+ throw new IllegalArgumentException("Unrecognized value for setting " + key + ": " + value); //$NON-NLS-1$ //$NON-NLS-2$
+ setter.accept((String) value);
+ }
+ }
+
+ private void setBoolean(Map<String, String> settings, String key, String trueValue, Consumer<Boolean> setter) {
+ Object value = settings.get(key);
+ if (value != null)
+ setter.accept(trueValue.equals(value));
+ }
+
/**
* This method is used to handle deprecated preferences which might be replaced by
* one or more preferences.
@@ -2476,6 +2508,51 @@
this.insert_new_line_after_annotation_on_local_variable = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnLocalVariableOption);
}
}
+
+ // insert new line between empty braces -> keep braced code on one line
+ HashMap<Boolean, String> insertToOneLine = new HashMap<>();
+ insertToOneLine.put(true, DefaultCodeFormatterConstants.ONE_LINE_NEVER);
+ insertToOneLine.put(false, DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY);
+ if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE) == null) {
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION, JavaCore.INSERT,
+ v -> this.keep_annotation_declaration_on_one_line = insertToOneLine.get(v));
+ }
+ if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE) == null) {
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION, JavaCore.INSERT,
+ v -> this.keep_anonymous_type_declaration_on_one_line = insertToOneLine.get(v));
+ }
+ if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE) == null) {
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, JavaCore.INSERT,
+ v -> this.keep_if_then_body_block_on_one_line = insertToOneLine.get(v));
+ }
+ if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE) == null) {
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, JavaCore.INSERT,
+ v -> this.keep_loop_body_block_on_one_line = insertToOneLine.get(v));
+ }
+ if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE) == null) {
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, JavaCore.INSERT,
+ v -> this.keep_lambda_body_block_on_one_line = insertToOneLine.get(v));
+ }
+ if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE) == null) {
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, JavaCore.INSERT,
+ v -> this.keep_code_block_on_one_line = insertToOneLine.get(v));
+ }
+ if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE) == null) {
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT, JavaCore.INSERT,
+ v -> this.keep_enum_constant_declaration_on_one_line = insertToOneLine.get(v));
+ }
+ if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE) == null) {
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION, JavaCore.INSERT,
+ v -> this.keep_enum_declaration_on_one_line = insertToOneLine.get(v));
+ }
+ if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE) == null) {
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY, JavaCore.INSERT,
+ v -> this.keep_method_body_on_one_line = insertToOneLine.get(v));
+ }
+ if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE) == null) {
+ setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION, JavaCore.INSERT,
+ v -> this.keep_type_declaration_on_one_line = insertToOneLine.get(v));
+ }
}
public void setDefaultSettings() {
@@ -2596,13 +2673,17 @@
this.insert_new_line_before_else_in_if_statement = false;
this.insert_new_line_before_finally_in_try_statement = false;
this.insert_new_line_before_while_in_do_statement = false;
- this.insert_new_line_in_empty_anonymous_type_declaration = true;
- this.insert_new_line_in_empty_block = true;
- this.insert_new_line_in_empty_annotation_declaration = true;
- this.insert_new_line_in_empty_enum_constant = true;
- this.insert_new_line_in_empty_enum_declaration = true;
- this.insert_new_line_in_empty_method_body = true;
- this.insert_new_line_in_empty_type_declaration = true;
+ this.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_simple_getter_setter_on_one_line = false;
this.insert_space_after_and_in_type_parameter = true;
this.insert_space_after_assignment_operator = true;
this.insert_space_after_at_in_annotation = false;
@@ -2916,13 +2997,16 @@
this.insert_new_line_before_else_in_if_statement = false;
this.insert_new_line_before_finally_in_try_statement = false;
this.insert_new_line_before_while_in_do_statement = false;
- this.insert_new_line_in_empty_anonymous_type_declaration = true;
- this.insert_new_line_in_empty_block = true;
- this.insert_new_line_in_empty_annotation_declaration = true;
- this.insert_new_line_in_empty_enum_constant = true;
- this.insert_new_line_in_empty_enum_declaration = true;
- this.insert_new_line_in_empty_method_body = true;
- this.insert_new_line_in_empty_type_declaration = true;
+ this.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+ this.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
this.insert_space_after_and_in_type_parameter = true;
this.insert_space_after_assignment_operator = true;
this.insert_space_after_at_in_annotation = false;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
index b0b16b8..9dc434e 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
@@ -150,8 +150,7 @@
breakLineBefore(node);
handleBracedCode(node, node.getName(), this.options.brace_position_for_type_declaration,
- this.options.indent_body_declarations_compare_to_type_header,
- this.options.insert_new_line_in_empty_type_declaration);
+ this.options.indent_body_declarations_compare_to_type_header);
this.declarationModifierVisited = false;
return true;
@@ -203,8 +202,7 @@
@Override
public boolean visit(EnumDeclaration node) {
handleBracedCode(node, node.getName(), this.options.brace_position_for_enum_declaration,
- this.options.indent_body_declarations_compare_to_enum_declaration_header,
- this.options.insert_new_line_in_empty_enum_declaration);
+ this.options.indent_body_declarations_compare_to_enum_declaration_header);
handleBodyDeclarations(node.bodyDeclarations());
List<EnumConstantDeclaration> enumConstants = node.enumConstants();
@@ -236,8 +234,7 @@
@Override
public boolean visit(AnnotationTypeDeclaration node) {
handleBracedCode(node, node.getName(), this.options.brace_position_for_annotation_type_declaration,
- this.options.indent_body_declarations_compare_to_annotation_declaration_header,
- this.options.insert_new_line_in_empty_annotation_declaration);
+ this.options.indent_body_declarations_compare_to_annotation_declaration_header);
handleBodyDeclarations(node.bodyDeclarations());
if (node.getModifiers() == 0)
@@ -251,12 +248,10 @@
public boolean visit(AnonymousClassDeclaration node) {
if (node.getParent() instanceof EnumConstantDeclaration) {
handleBracedCode(node, null, this.options.brace_position_for_enum_constant,
- this.options.indent_body_declarations_compare_to_enum_constant_header,
- this.options.insert_new_line_in_empty_enum_constant);
+ this.options.indent_body_declarations_compare_to_enum_constant_header);
} else {
handleBracedCode(node, null, this.options.brace_position_for_anonymous_type_declaration,
- this.options.indent_body_declarations_compare_to_type_header,
- this.options.insert_new_line_in_empty_anonymous_type_declaration);
+ this.options.indent_body_declarations_compare_to_type_header);
}
handleBodyDeclarations(node.bodyDeclarations());
return true;
@@ -276,9 +271,7 @@
String bracePosition = node.isConstructor() ? this.options.brace_position_for_constructor_declaration
: this.options.brace_position_for_method_declaration;
- handleBracedCode(node.getBody(), null, bracePosition,
- this.options.indent_statements_compare_to_body,
- this.options.insert_new_line_in_empty_method_body);
+ handleBracedCode(node.getBody(), null, bracePosition, this.options.indent_statements_compare_to_body);
Token openBrace = this.tm.firstTokenIn(node.getBody(), TokenNameLBRACE);
if (openBrace.getLineBreaksAfter() > 0) // if not, these are empty braces
openBrace.putLineBreaksAfter(this.options.blank_lines_at_beginning_of_method_body + 1);
@@ -287,18 +280,14 @@
@Override
public boolean visit(Block node) {
- if (this.options.keep_guardian_clause_on_one_line && this.tm.isGuardClause(node))
- return true;
-
List<Statement> statements = node.statements();
for (Statement statement : statements) {
if (this.options.put_empty_statement_on_new_line || !(statement instanceof EmptyStatement))
breakLineBefore(statement);
}
- if (node.getParent().getLength() == 0)
- return true; // this is a fake block created by parsing in statements mode
-
ASTNode parent = node.getParent();
+ if (parent.getLength() == 0)
+ return true; // this is a fake block created by parsing in statements mode
if (parent instanceof MethodDeclaration)
return true; // braces have been handled in #visit(MethodDeclaration)
@@ -312,8 +301,7 @@
} else if (parent instanceof LambdaExpression) {
bracePosition = this.options.brace_position_for_lambda_body;
}
- handleBracedCode(node, null, bracePosition, this.options.indent_statements_compare_to_block,
- this.options.insert_new_line_in_empty_block);
+ handleBracedCode(node, null, bracePosition, this.options.indent_statements_compare_to_block);
return true;
}
@@ -321,7 +309,7 @@
@Override
public boolean visit(SwitchStatement node) {
handleBracedCode(node, node.getExpression(), this.options.brace_position_for_switch,
- this.options.indent_switchstatements_compare_to_switch, true);
+ this.options.indent_switchstatements_compare_to_switch);
List<Statement> statements = node.statements();
if (this.options.indent_switchstatements_compare_to_cases) {
@@ -690,8 +678,7 @@
// using settings for type declaration and fields for now, add new settings if necessary
breakLineBefore(node);
handleBracedCode(node, node.getName(), this.options.brace_position_for_type_declaration,
- this.options.indent_body_declarations_compare_to_type_header,
- this.options.insert_new_line_in_empty_type_declaration);
+ this.options.indent_body_declarations_compare_to_type_header);
List<ModuleDirective> statements = node.moduleStatements();
ModuleDirective previous = null;
@@ -711,8 +698,7 @@
this.tm.firstTokenIn(node, -1).breakBefore();
}
- private void handleBracedCode(ASTNode node, ASTNode nodeBeforeOpenBrace, String bracePosition, boolean indentBody,
- boolean newLineInEmpty) {
+ private void handleBracedCode(ASTNode node, ASTNode nodeBeforeOpenBrace, String bracePosition, boolean indentBody) {
int openBraceIndex = nodeBeforeOpenBrace == null
? this.tm.firstIndexIn(node, TokenNameLBRACE)
: this.tm.firstIndexAfter(nodeBeforeOpenBrace, TokenNameLBRACE);
@@ -721,18 +707,9 @@
Token closeBraceToken = this.tm.get(closeBraceIndex);
handleBracePosition(openBraceToken, closeBraceIndex, bracePosition);
- boolean isEmpty = true;
- for (int i = openBraceIndex + 1; i < closeBraceIndex; i++) {
- if (!this.tm.get(i).isComment()) {
- isEmpty = false;
- break;
- }
- }
+ openBraceToken.breakAfter();
+ closeBraceToken.breakBefore();
- if (!isEmpty || newLineInEmpty) {
- openBraceToken.breakAfter();
- closeBraceToken.breakBefore();
- }
if (indentBody) {
adjustEmptyLineAfter(openBraceIndex, 1);
this.tm.get(openBraceIndex + 1).indent();
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OneLineEnforcer.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OneLineEnforcer.java
new file mode 100644
index 0000000..9d9763f
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OneLineEnforcer.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 2018 Mateusz Matela 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:
+ * Mateusz Matela <mateusz.matela@gmail.com> - Initial API and implementation
+ *
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameLBRACE;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameRBRACE;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamewhile;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.Assignment;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.DoStatement;
+import org.eclipse.jdt.core.dom.EnhancedForStatement;
+import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.ExpressionStatement;
+import org.eclipse.jdt.core.dom.ForStatement;
+import org.eclipse.jdt.core.dom.IfStatement;
+import org.eclipse.jdt.core.dom.LambdaExpression;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.ModuleDeclaration;
+import org.eclipse.jdt.core.dom.PrimitiveType;
+import org.eclipse.jdt.core.dom.ReturnStatement;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.dom.ThrowStatement;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.WhileStatement;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+
+/** Implementation of the "Keep braced code on one line" feature. */
+public class OneLineEnforcer extends ASTVisitor {
+ private final TokenManager tm;
+ private final DefaultCodeFormatterOptions options;
+
+ public OneLineEnforcer(TokenManager tokenManager, DefaultCodeFormatterOptions options) {
+ this.tm = tokenManager;
+ this.options = options;
+ }
+
+ @Override
+ public void endVisit(TypeDeclaration node) {
+ if (node.getParent().getLength() == 0)
+ return; // this is a fake block created by parsing in statements mode
+ tryKeepOnOneLine(node, node.getName(), node.bodyDeclarations(), this.options.keep_type_declaration_on_one_line);
+ }
+
+ @Override
+ public void endVisit(EnumDeclaration node) {
+ List<ASTNode> items = new ArrayList<>();
+ items.addAll(node.bodyDeclarations());
+ items.addAll(node.enumConstants());
+ tryKeepOnOneLine(node, node.getName(), items, this.options.keep_enum_declaration_on_one_line);
+ }
+
+ @Override
+ public void endVisit(AnnotationTypeDeclaration node) {
+ tryKeepOnOneLine(node, node.getName(), node.bodyDeclarations(),
+ this.options.keep_annotation_declaration_on_one_line);
+ }
+
+ @Override
+ public void endVisit(AnonymousClassDeclaration node) {
+ if (node.getParent() instanceof EnumConstantDeclaration) {
+ tryKeepOnOneLine(node, null, node.bodyDeclarations(),
+ this.options.keep_enum_constant_declaration_on_one_line);
+ } else {
+ tryKeepOnOneLine(node, null, node.bodyDeclarations(),
+ this.options.keep_anonymous_type_declaration_on_one_line);
+ }
+ }
+
+ @Override
+ public void endVisit(Block node) {
+ ASTNode parent = node.getParent();
+ List<Statement> statements = node.statements();
+ if (parent.getLength() == 0)
+ return; // this is a fake block created by parsing in statements mode
+ String oneLineOption;
+ if (parent instanceof MethodDeclaration) {
+ oneLineOption = this.options.keep_method_body_on_one_line;
+ if (this.options.keep_simple_getter_setter_on_one_line) {
+ MethodDeclaration method = (MethodDeclaration) parent;
+ String name = method.getName().getIdentifier();
+ Type returnType = method.getReturnType2();
+ boolean returnsVoid = returnType instanceof PrimitiveType
+ && ((PrimitiveType) returnType).getPrimitiveTypeCode() == PrimitiveType.VOID;
+ boolean isGetter = name.matches("(is|get)\\p{Lu}.*") //$NON-NLS-1$
+ && !method.isConstructor() && !returnsVoid && method.parameters().isEmpty()
+ && statements.size() == 1 && statements.get(0) instanceof ReturnStatement;
+ boolean isSetter = name.matches("set\\p{Lu}.*") //$NON-NLS-1$
+ && !method.isConstructor() && returnsVoid && method.parameters().size() == 1
+ && statements.size() == 1 && statements.get(0) instanceof ExpressionStatement
+ && ((ExpressionStatement) statements.get(0)).getExpression() instanceof Assignment;
+ if (isGetter || isSetter)
+ oneLineOption = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ }
+ } else if (parent instanceof IfStatement && ((IfStatement) parent).getElseStatement() == null) {
+ oneLineOption = this.options.keep_if_then_body_block_on_one_line;
+ if (this.options.keep_guardian_clause_on_one_line) {
+ boolean isGuardian = statements.size() == 1 && (statements.get(0) instanceof ReturnStatement
+ || statements.get(0) instanceof ThrowStatement);
+ // guard clause cannot start with a comment: https://bugs.eclipse.org/58565
+ int openBraceIndex = this.tm.firstIndexIn(node, TokenNameLBRACE);
+ isGuardian = isGuardian && !this.tm.get(openBraceIndex + 1).isComment();
+ if (isGuardian)
+ oneLineOption = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+ }
+ } else if (parent instanceof LambdaExpression) {
+ oneLineOption = this.options.keep_lambda_body_block_on_one_line;
+ } else if (parent instanceof ForStatement || parent instanceof EnhancedForStatement
+ || parent instanceof WhileStatement) {
+ oneLineOption = this.options.keep_loop_body_block_on_one_line;
+ } else if (parent instanceof DoStatement) {
+ oneLineOption = this.options.keep_loop_body_block_on_one_line;
+ int openBraceIndex = this.tm.firstIndexIn(node, TokenNameLBRACE);
+ int closeBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
+ Token whileToken = this.tm.firstTokenAfter(node, TokenNamewhile);
+ int lastIndex = whileToken.getLineBreaksBefore() == 0 ? this.tm.lastIndexIn(parent, -1) : closeBraceIndex;
+ tryKeepOnOneLine(openBraceIndex, closeBraceIndex, lastIndex, statements, oneLineOption);
+ return;
+ } else {
+ oneLineOption = this.options.keep_code_block_on_one_line;
+ }
+ tryKeepOnOneLine(node, null, statements, oneLineOption);
+ }
+
+ @Override
+ public void endVisit(ModuleDeclaration node) {
+ tryKeepOnOneLine(node, node.getName(), node.moduleStatements(), this.options.keep_type_declaration_on_one_line);
+ }
+
+ private void tryKeepOnOneLine(ASTNode node, ASTNode nodeBeforeOpenBrace, List<? extends ASTNode> items,
+ String oneLineOption) {
+ int openBraceIndex = nodeBeforeOpenBrace == null ? this.tm.firstIndexIn(node, TokenNameLBRACE)
+ : this.tm.firstIndexAfter(nodeBeforeOpenBrace, TokenNameLBRACE);
+ int closeBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
+ tryKeepOnOneLine(openBraceIndex, closeBraceIndex, closeBraceIndex, items, oneLineOption);
+ }
+
+ private void tryKeepOnOneLine(int openBraceIndex, int closeBraceIndex, int lastIndex, List<? extends ASTNode> items,
+ String oneLineOption) {
+ if (DefaultCodeFormatterConstants.ONE_LINE_NEVER.equals(oneLineOption))
+ return;
+ if (DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY.equals(oneLineOption) && !items.isEmpty())
+ return;
+ if (DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM.equals(oneLineOption) && items.size() > 1)
+ return;
+ if (DefaultCodeFormatterConstants.ONE_LINE_PRESERVE.equals(oneLineOption)
+ && this.tm.countLineBreaksBetween(this.tm.get(openBraceIndex), this.tm.get(lastIndex)) > 0)
+ return;
+
+ Set<Integer> breakIndexes = items.stream().map(n -> this.tm.firstIndexIn(n, -1)).collect(Collectors.toSet());
+ breakIndexes.add(openBraceIndex + 1);
+ breakIndexes.add(closeBraceIndex);
+ Token prev = this.tm.get(openBraceIndex);
+ int startPos = this.tm.getPositionInLine(openBraceIndex);
+ int pos = startPos + this.tm.getLength(prev, startPos);
+ for (int i = openBraceIndex + 1; i <= lastIndex; i++) {
+ Token token = this.tm.get(i);
+ int preexistingBreaks = this.tm.countLineBreaksBetween(prev, token);
+ if (this.options.number_of_empty_lines_to_preserve > 0 && preexistingBreaks > 1)
+ return; // blank line will be preserved
+ boolean isSpace = prev.isSpaceAfter() || token.isSpaceBefore();
+ if (prev.isComment() || token.isComment()) {
+ if (preexistingBreaks > 0)
+ return; // line break around a comment will be preserved
+ char charBefore = this.tm.charAt(token.originalStart - 1);
+ isSpace = isSpace || charBefore == ' ' || charBefore == '\t';
+ }
+ if (prev.getLineBreaksAfter() > 0 || token.getLineBreaksBefore() > 0) {
+ if (!breakIndexes.contains(i))
+ return; // extra line break within an item, can't remove it
+ isSpace = isSpace || !(i == closeBraceIndex && i == openBraceIndex + 1);
+ }
+ if (isSpace)
+ pos++;
+ pos += this.tm.getLength(token, pos);
+ prev = token;
+ }
+ if (!items.isEmpty()) {
+ if (items.get(0).getParent().getParent() instanceof LambdaExpression)
+ pos -= startPos; // lambda body could be put in a wrapped line, so only check its own width
+ if (pos > this.options.page_width)
+ return; // line width limit exceeded
+ }
+
+ for (Integer i : breakIndexes) {
+ prev = this.tm.get(i - 1);
+ prev.clearLineBreaksAfter();
+ Token token = this.tm.get(i);
+ token.clearLineBreaksBefore();
+ if (!items.isEmpty())
+ token.spaceBefore();
+ }
+ }
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
index 5c933ff..96353d1 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
@@ -571,11 +571,6 @@
Statement thenStatement = node.getThenStatement();
handleTokenBefore(thenStatement, TokenNameRPAREN, this.options.insert_space_before_closing_paren_in_if, false);
- if (thenStatement instanceof Block && this.tm.isGuardClause((Block) thenStatement)) {
- handleToken(thenStatement, TokenNameLBRACE, false, true);
- this.tm.lastTokenIn(node, TokenNameRBRACE).spaceBefore();
- }
-
handleLoopBody(thenStatement);
handleSemicolon(thenStatement);
return true;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
index 5783e12..4e42073 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2016 Mateusz Matela and others.
+ * Copyright (c) 2014, 2018 Mateusz Matela and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,7 +15,6 @@
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_BLOCK;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_JAVADOC;
-import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameLBRACE;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameNotAToken;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameStringLiteral;
@@ -27,10 +26,6 @@
import java.util.regex.Pattern;
import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.Block;
-import org.eclipse.jdt.core.dom.IfStatement;
-import org.eclipse.jdt.core.dom.ReturnStatement;
-import org.eclipse.jdt.core.dom.ThrowStatement;
import org.eclipse.jdt.internal.formatter.Token.WrapMode;
import org.eclipse.jdt.internal.formatter.linewrap.CommentWrapExecutor;
@@ -177,21 +172,6 @@
return this.tokens.iterator();
}
- public boolean isGuardClause(Block node) {
- if (node.statements().size() != 1)
- return false;
- ASTNode parent = node.getParent();
- if (!(parent instanceof IfStatement) || ((IfStatement) parent).getElseStatement() != null)
- return false;
- Object statement = node.statements().get(0);
- if (!(statement instanceof ReturnStatement) && !(statement instanceof ThrowStatement))
- return false;
- // guard clause cannot start with a comment
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=58565
- int openBraceIndex = firstIndexIn(node, TokenNameLBRACE);
- return !get(openBraceIndex + 1).isComment();
- }
-
public int firstIndexIn(ASTNode node, int tokenType) {
int index = findIndex(node.getStartPosition(), tokenType, true);
assert tokenInside(node, index);
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/Aligner.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/Aligner.java
index f71cf15..011565e 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/Aligner.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/Aligner.java
@@ -93,7 +93,7 @@
}
public void handleAlign(List<BodyDeclaration> bodyDeclarations) {
- if (!this.options.align_type_members_on_columns)
+ if (!this.options.align_type_members_on_columns || areKeptOnOneLine(bodyDeclarations))
return;
List<List<FieldDeclaration>> fieldGroups = toAlignGroups(bodyDeclarations,
n -> optionalCast(n, FieldDeclaration.class));
@@ -110,12 +110,18 @@
public void handleAlign(Block block) {
List<Statement> statements = block.statements();
+ if (areKeptOnOneLine(statements))
+ return;
if (this.options.align_variable_declarations_on_columns)
alignDeclarations(statements);
if (this.options.align_assignment_statements_on_columns)
alignAssignmentStatements(statements);
}
+ private boolean areKeptOnOneLine(List<? extends ASTNode> nodes) {
+ return nodes.stream().allMatch(n -> this.tm.firstTokenIn(n, -1).getLineBreaksBefore() == 0);
+ }
+
private void alignDeclarations(List<Statement> statements) {
List<List<VariableDeclarationStatement>> variableGroups = toAlignGroups(statements,
n -> optionalCast(n, VariableDeclarationStatement.class));
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
index ca9a2c6..cf7ba63 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
@@ -186,10 +186,10 @@
* temporary values used when calling {@link #handleWrap(int)} to avoid ArrayList initialization and long lists of
* parameters
*/
- private List<Integer> wrapIndexes = new ArrayList<Integer>();
+ private List<Integer> wrapIndexes = new ArrayList<>();
/** Indexes for wraps that shouldn't happen but should be indented if cannot be removed */
- private List<Integer> secondaryWrapIndexes = new ArrayList<Integer>();
- private List<Float> wrapPenalties = new ArrayList<Float>();
+ private List<Integer> secondaryWrapIndexes = new ArrayList<>();
+ private List<Float> wrapPenalties = new ArrayList<>();
private int wrapParentIndex = -1;
private int wrapGroupEnd = -1;
@@ -773,6 +773,23 @@
public boolean visit(LambdaExpression node) {
if (node.getBody() instanceof Block) {
forceContinuousWrapping(node.getBody(), this.tm.firstIndexIn(node, -1));
+
+ List<Statement> statements = ((Block) node.getBody()).statements();
+ if (!statements.isEmpty()) {
+ int openBraceIndex = this.tm.firstIndexBefore(statements.get(0), TokenNameLBRACE);
+ int closeBraceIndex = this.tm.firstIndexAfter(statements.get(statements.size() - 1), TokenNameRBRACE);
+ boolean areKeptOnOneLine = statements.stream()
+ .allMatch(n -> this.tm.firstTokenIn(n, -1).getLineBreaksBefore() == 0);
+ if (areKeptOnOneLine) {
+ for (Statement statement : statements)
+ this.wrapIndexes.add(this.tm.firstIndexIn(statement, -1));
+ this.wrapParentIndex = openBraceIndex;
+ this.wrapGroupEnd = closeBraceIndex;
+ handleWrap(Alignment.M_ONE_PER_LINE_SPLIT, node);
+ this.tm.get(closeBraceIndex).setWrapPolicy(new WrapPolicy(WrapMode.TOP_PRIORITY, openBraceIndex,
+ closeBraceIndex, 0, this.currentDepth, 1, false, false));
+ }
+ }
}
if (node.hasParentheses()) {
List<VariableDeclaration> parameters = node.parameters();
@@ -1036,6 +1053,8 @@
} else if (parentNode instanceof DoStatement) {
extraIndent = 0;
this.wrapParentIndex = this.tm.firstIndexIn(parentNode, -1); // only if !indoentOnColumn
+ } else if (parentNode instanceof LambdaExpression) {
+ extraIndent = 1;
} else if ((wrappingOption & Alignment.M_INDENT_BY_ONE) != 0) {
extraIndent = 1;
} else if (parentNode instanceof ArrayInitializer) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index df16101..1aad2d2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -3058,6 +3058,21 @@
}
/**
+ * Returns whether the given version of Java or Java Runtime is supported
+ * by the Java Development Toolkit.
+ *
+ * A true indicates that the given version is supported. For e.g., if the argument
+ * is <code>11.0.1</code> and {@link #getAllVersions()} contains <code>11</code>,
+ * the method returns <code>true</code>.
+ *
+ * @return a boolean indicating support for the given version of Java or Java Runtime.
+ * @since 3.16
+ */
+ public static boolean isSupportedJavaVersion(String version) {
+ return CompilerOptions.versionToJdkLevel(version, false) > 0;
+ }
+
+ /**
* Configurable option value: {@value}.
* @since 2.0
* @category OptionValue
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
index 6dff56a..c8dbd47 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
@@ -246,7 +246,14 @@
// TODO(sxenos): setup the external annotation provider if the IBinaryType came from the index
if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
JavaProject javaProject = (JavaProject) getAncestor(IJavaElement.JAVA_PROJECT);
- IClasspathEntry entry = javaProject.getClasspathEntryFor(getPath());
+ IClasspathEntry entry;
+ try {
+ entry = javaProject.getClasspathEntryFor(getPath());
+ } catch (JavaModelException jme) {
+ // Access via cached ClassFile/PF/PFR of a closed project?
+ // Ignore and continue with result undecorated
+ return result;
+ }
if (entry != null) {
PackageFragment pkg = (PackageFragment) getParent();
String entryName = Util.concatWith(pkg.names, getElementName(), '/');