Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2023-03-30 15:48:39 +0000
committerStephan Herrmann2023-03-30 15:48:39 +0000
commitdb1b02a94a8b8d4fa852179d5aa01ccda802d1a6 (patch)
treed79ea02da2d75e73b18f3f95d43537b6ba0ac870
parent368c8fd108ff3f873eb5cf25c0f2b088c06349f7 (diff)
downloadorg.eclipse.objectteams-db1b02a94a8b8d4fa852179d5aa01ccda802d1a6.tar.gz
org.eclipse.objectteams-db1b02a94a8b8d4fa852179d5aa01ccda802d1a6.tar.xz
org.eclipse.objectteams-db1b02a94a8b8d4fa852179d5aa01ccda802d1a6.zip
(right before the Java20 merge)
-rw-r--r--org.eclipse.jdt.core.compiler.batch/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jdt.core.compiler.batch/pom.xml4
-rw-r--r--org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java5
-rw-r--r--org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TextBlock.java8
-rw-r--r--org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java7
-rw-r--r--org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java16
-rw-r--r--org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java32
-rw-r--r--org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java30
-rw-r--r--org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jdt.core.tests.compiler/pom.xml5
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_15.java254
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_1_5.java (renamed from org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiterals15Test.java)6
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java90
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java3
-rw-r--r--org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jdt.core.tests.model/pom.xml4
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java18
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests11.java189
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java46
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs16Tests.java40
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java78
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java61
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java2
-rw-r--r--org.eclipse.jdt.core/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java106
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java3
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java13
-rw-r--r--org.eclipse.jdt.core/pom.xml4
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java6
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java34
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java40
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java3
32 files changed, 998 insertions, 119 deletions
diff --git a/org.eclipse.jdt.core.compiler.batch/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.compiler.batch/META-INF/MANIFEST.MF
index 7fb103483..553499fea 100644
--- a/org.eclipse.jdt.core.compiler.batch/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.compiler.batch/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@ Main-Class: org.eclipse.jdt.internal.compiler.batch.Main
Bundle-ManifestVersion: 2
Bundle-Name: Eclipse Compiler for Java(TM)
Bundle-SymbolicName: org.eclipse.jdt.core.compiler.batch
-Bundle-Version: 3.33.0.OTDT_r282_qualifier
+Bundle-Version: 3.33.100.OTDT_r282_qualifier
Bundle-ClassPath: .
Bundle-Vendor: Eclipse.org
Automatic-Module-Name: org.eclipse.jdt.core.compiler.batch
diff --git a/org.eclipse.jdt.core.compiler.batch/pom.xml b/org.eclipse.jdt.core.compiler.batch/pom.xml
index b9fa6f2a9..c19acde72 100644
--- a/org.eclipse.jdt.core.compiler.batch/pom.xml
+++ b/org.eclipse.jdt.core.compiler.batch/pom.xml
@@ -14,10 +14,10 @@
<parent>
<artifactId>eclipse.jdt.core</artifactId>
<groupId>org.eclipse.jdt</groupId>
- <version>4.27.0-SNAPSHOT</version>
+ <version>4.28.0-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jdt.core.compiler.batch</artifactId>
- <version>3.33.0-SNAPSHOT</version>
+ <version>3.33.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<properties>
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 2346f40da..68e6b2dfb 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2023 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -17,6 +17,7 @@
* Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
* Frits Jalvingh - contributions for bug 533830.
* Red Hat Inc. - add module-info Javadoc support
+ * Red Hat Inc. - add NLS support for Text Blocks
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -847,7 +848,7 @@ void reportNLSProblems() {
int i = 0;
stringLiteralsLoop: for (; i < stringLiteralsLength; i++) {
literal = this.stringLiterals[i];
- final int literalLineNumber = literal.lineNumber;
+ final int literalLineNumber = literal instanceof TextBlock ? ((TextBlock)literal).endLineNumber : literal.lineNumber;
if (lastLineNumber != literalLineNumber) {
indexInLine = 1;
lastLineNumber = literalLineNumber;
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TextBlock.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TextBlock.java
index a4e8a571a..e092b6de9 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TextBlock.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TextBlock.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2019 IBM Corporation and others.
+ * Copyright (c) 2019, 2023 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -14,7 +14,11 @@ package org.eclipse.jdt.internal.compiler.ast;
public class TextBlock extends StringLiteral {
- public TextBlock(char[] token, int start, int end, int lineNumber) {
+ public int endLineNumber;
+
+ public TextBlock(char[] token, int start, int end, int lineNumber, int endLineNumber) {
super(token, start,end, lineNumber);
+ this.endLineNumber= endLineNumber - 1; // line number is 1 based
}
+
}
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java
index 5ad8ee805..9947ef646 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java
@@ -39,6 +39,8 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
*/
public class IntersectionTypeBinding18 extends ReferenceBinding {
+ private static final char[] INTERSECTION_PACKAGE_NAME = "<package intersection>".toCharArray(); //$NON-NLS-1$
+
public ReferenceBinding [] intersectingTypes;
private ReferenceBinding javaLangObject;
int length;
@@ -256,6 +258,11 @@ public class IntersectionTypeBinding18 extends ReferenceBinding {
}
@Override
+ public char[] qualifiedPackageName() {
+ return INTERSECTION_PACKAGE_NAME;
+ }
+
+ @Override
public char[] qualifiedSourceName() {
StringBuilder qualifiedSourceName = new StringBuilder(16);
for (int i = 0; i < this.length; i++) {
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 7637348c9..d63ca0d12 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -2881,7 +2881,7 @@ public MethodBinding[] methods() {
computeRecordComponents();
MethodBinding recordExplicitCanon = checkAndGetExplicitCanonicalConstructors();
if (recordExplicitCanon != null) {
- if (recordCanonIndex != -1 ) {
+ if (recordCanonIndex != -1 && resolvedMethods[recordCanonIndex] instanceof SyntheticMethodBinding) {
removeSyntheticRecordCanonicalConstructor((SyntheticMethodBinding) resolvedMethods[recordCanonIndex]);
resolvedMethods[recordCanonIndex] = null;
failed++;
@@ -3098,6 +3098,15 @@ public MethodBinding[] methods() {
// handle forward references to potential default abstract methods
addDefaultAbstractMethods();
this.tagBits |= TagBits.AreMethodsComplete;
+ if (this.isRecordDeclaration) {
+ /* https://github.com/eclipse-jdt/eclipse.jdt.core/issues/365 */
+ for (int i = 0; i < this.methods.length; i++) {
+ MethodBinding method = this.methods[i];
+ if ((method.tagBits & TagBits.AnnotationSafeVarargs) == 0 && method.sourceMethod() != null) {
+ checkAndFlagHeapPollution(method, method.sourceMethod());
+ }
+ }
+ }
}
return this.methods;
}
@@ -3586,7 +3595,10 @@ private MethodBinding resolveTypesWithSuspendedTempErrorHandlingPolicy(MethodBin
methodDecl.scope.problemReporter().safeVarargsOnNonFinalInstanceMethod(method);
}
} else {
- checkAndFlagHeapPollution(method, methodDecl);
+ /* https://github.com/eclipse-jdt/eclipse.jdt.core/issues/365 */
+ if (!this.isRecordDeclaration) {
+ checkAndFlagHeapPollution(method, methodDecl);
+ }
}
}
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
index 2daab753f..bb71d4d59 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
@@ -1841,7 +1841,9 @@ public abstract class AbstractCommentParser implements JavadocTagConstants {
}
consumeToken();
token = readTokenSafely();
- if (token==TerminalTokens.TokenNameERROR||token==TerminalTokens.TokenNameStringLiteral){
+ if (token==TerminalTokens.TokenNameERROR
+ || token==TerminalTokens.TokenNameStringLiteral
+ || token==TerminalTokens.TokenNameIdentifier){
regionName = this.scanner.getCurrentTokenString();
consumeToken();
lastIndex = regionName.length() - 1;
@@ -2007,8 +2009,9 @@ public abstract class AbstractCommentParser implements JavadocTagConstants {
indexOfLastComment = indexOfLastSingleComment(commentLine.substring(2),noSingleLineComm);
commentStr = commentLine.substring(indexOfLastComment+2);
}
- Scanner commentScanner = new Scanner(false, false, false, this.scanner.sourceLevel, this.scanner.complianceLevel,
- null, null, false, false);
+ Scanner commentScanner = new JavadocScanner(false, false, false/* nls */, this.scanner.sourceLevel, this.scanner.complianceLevel,
+ null/* taskTags */, null/* taskPriorities */, false/* taskCaseSensitive */, false, true, true);
+
if (commentStr.startsWith("//")) { //$NON-NLS-1$
commentStr = commentStr.substring(2);
}
@@ -2064,6 +2067,25 @@ public abstract class AbstractCommentParser implements JavadocTagConstants {
isRegion = true;
break;
default:
+ if (getRegionValue) {
+ String regionStr = commentScanner.getCurrentTokenString();
+ regionStr = stripQuotes(regionStr);
+ if (START.equals(attribute) && regionStr.equals(region)) {
+ insideRegion = true;
+ regionStarted = true;
+ }
+ if (END.equals(attribute)) {
+ if (regionStr.equals(region)) {
+ insideRegion = false;
+ }
+ stack.removeFirst();
+ }
+ if (!END.equals(attribute) && insideRegion) {
+ stack.addFirst(attribute);
+ }
+ attribute = null;
+ getRegionValue = false;
+ }
isRegion = false;
break;
}
@@ -2402,7 +2424,9 @@ public abstract class AbstractCommentParser implements JavadocTagConstants {
case TerminalTokens.TokenNameIdentifier:
if (processValue) {
value = slScanner.getCurrentTokenString();
- if (map.get(attribute) == null) {
+ if (REGION.equals(attribute)) {
+ regionName = value;
+ } else if (map.get(attribute) == null) {
map.put(attribute, value);
if ((attribute.equals(SUBSTRING) && (map.get(REGEX) != null))
|| (attribute.equals(REGEX) && (map.get(SUBSTRING) != null))) {
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java
index 749d4ec44..dd012b5a5 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2022 IBM Corporation and others.
+ * Copyright (c) 2000, 2023 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -40,6 +40,7 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -12325,12 +12326,15 @@ protected void consumeTextBlock() {
textBlock2,
this.scanner.startPosition,
this.scanner.currentPosition - 1,
- Util.getLineNumber(this.scanner.startPosition, this.scanner.lineEnds, 0, this.scanner.linePtr));
+ Util.getLineNumber(this.scanner.startPosition, this.scanner.lineEnds, 0, this.scanner.linePtr),
+ Util.getLineNumber(this.scanner.currentPosition - 1, this.scanner.lineEnds, 0, this.scanner.linePtr));
+ this.compilationUnit.recordStringLiteral(textBlock, this.currentElement != null);
} else {
textBlock = new TextBlock(
textBlock2,
this.scanner.startPosition,
this.scanner.currentPosition - 1,
+ 0,
0);
}
pushOnExpressionStack(textBlock);
@@ -13854,19 +13858,16 @@ protected void consumeRecordDeclaration() {
TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
this.recordNestedMethodLevels.remove(typeDecl);
problemReporter().validateJavaFeatureSupport(JavaFeature.RECORDS, typeDecl.sourceStart, typeDecl.sourceEnd);
+ /* create canonical constructor - check for the clash later at binding time */
+ /* https://github.com/eclipse-jdt/eclipse.jdt.core/issues/365 */
+ typeDecl.createDefaultConstructor(!(this.diet && this.dietInt == 0), true);
//convert constructor that do not have the type's name into methods
ConstructorDeclaration cd = typeDecl.getConstructor(this);
- if (cd == null) {
- /* create canonical constructor - check for the clash later at binding time */
- cd = typeDecl.createDefaultConstructor(!(this.diet && this.dietInt == 0), true);
- } else {
- if (cd instanceof CompactConstructorDeclaration
- || ((typeDecl.recordComponents == null || typeDecl.recordComponents.length == 0)
- && (cd.arguments == null || cd.arguments.length == 0))) {
- cd.bits |= ASTNode.IsCanonicalConstructor;
- }
+ if (cd instanceof CompactConstructorDeclaration
+ || ((typeDecl.recordComponents == null || typeDecl.recordComponents.length == 0)
+ && (cd.arguments == null || cd.arguments.length == 0))) {
+ cd.bits |= ASTNode.IsCanonicalConstructor;
}
-
if (this.scanner.containsAssertKeyword) {
typeDecl.bits |= ASTNode.ContainsAssertion;
}
@@ -13875,7 +13876,10 @@ protected void consumeRecordDeclaration() {
if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
typeDecl.bits |= ASTNode.UndocumentedEmptyBlock;
}
- TypeReference superClass = new QualifiedTypeReference(TypeConstants.JAVA_LANG_RECORD, new long[] {0});
+ char[][] sources = TypeConstants.JAVA_LANG_RECORD;
+ long[] poss = new long[sources.length];
+ Arrays.fill(poss, 0);
+ TypeReference superClass = new QualifiedTypeReference(sources, poss);
superClass.bits |= ASTNode.IsSuperType;
typeDecl.superclass = superClass;
typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
diff --git a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
index b444b1577..e63756694 100644
--- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.core.tests.compiler;singleton:=true
-Bundle-Version: 3.12.2100.qualifier
+Bundle-Version: 3.12.2200.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.jdt.core.tests.compiler,
diff --git a/org.eclipse.jdt.core.tests.compiler/pom.xml b/org.eclipse.jdt.core.tests.compiler/pom.xml
index f090fab59..ebb0d5f8a 100644
--- a/org.eclipse.jdt.core.tests.compiler/pom.xml
+++ b/org.eclipse.jdt.core.tests.compiler/pom.xml
@@ -15,11 +15,11 @@
<parent>
<artifactId>tests-pom</artifactId>
<groupId>org.eclipse.jdt</groupId>
- <version>4.27.0-SNAPSHOT</version>
+ <version>4.28.0-SNAPSHOT</version>
<relativePath>../tests-pom/</relativePath>
</parent>
<artifactId>org.eclipse.jdt.core.tests.compiler</artifactId>
- <version>3.12.2100-SNAPSHOT</version>
+ <version>3.12.2200-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
@@ -31,7 +31,6 @@
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
- <version>${tycho.version}</version>
<configuration>
<includes>
<include>org/eclipse/jdt/core/tests/compiler/parser/TestAll.class</include>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_15.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_15.java
new file mode 100644
index 000000000..4674ceec7
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_15.java
@@ -0,0 +1,254 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2014 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.compiler.regression;
+
+import java.util.Map;
+
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+import junit.framework.Test;
+
+@SuppressWarnings({ "unchecked", "rawtypes" })
+public class ExternalizeStringLiteralsTest_15 extends AbstractRegressionTest {
+
+private static final JavacTestOptions JAVAC_OPTIONS = new JavacTestOptions("-source 15");
+
+static {
+// TESTS_NAMES = new String[] { "test000" };
+// TESTS_NUMBERS = new int[] { 6 };
+// TESTS_RANGE = new int[] { 11, -1 };
+}
+public ExternalizeStringLiteralsTest_15(String name) {
+ super(name);
+}
+public static Test suite() {
+ return buildMinimalComplianceTestSuite(testClass(), F_15);
+}
+
+public void test001() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+
+ this.runNegativeTest(
+ true,
+ new String[] {
+ "X.java",
+ "public class X\n" +
+ "{\n" +
+ " String x = \"\"\"\n" +
+ " abcdefg\n" +
+ " hijklmn\n" +
+ " \"\"\";\n" +
+ "}"
+ },
+ null,
+ customOptions,
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " String x = \"\"\"\n" +
+ " abcdefg\n" +
+ " hijklmn\n" +
+ " \"\"\";\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Non-externalized string literal; it should be followed by //$NON-NLS-<n>$\n" +
+ "----------\n",
+ JAVAC_OPTIONS);
+}
+public void test002() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+
+ this.runNegativeTest(
+ true,
+ new String[] {
+ "X.java",
+ "public class X\n" +
+ "{\n" +
+ " String x = \"\"\"\n" +
+ " abcdefg\n" +
+ " hijklmn\n" +
+ " \"\"\"; //$NON-NLS-1$ //$NON-NLS-2$\n" +
+ "}"
+ },
+ null,
+ customOptions,
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " \"\"\"; //$NON-NLS-1$ //$NON-NLS-2$\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "Unnecessary $NON-NLS$ tag\n" +
+ "----------\n",
+ JAVAC_OPTIONS);
+}
+public void test003() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.WARNING);
+ customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+
+ this.runNegativeTest(
+ true,
+ new String[] {
+ "X.java",
+ "public class X\n" +
+ "{\n" +
+ " String x = \"\"\"\n" +
+ " abcdefg\n" +
+ " hijklmn\n" +
+ " \"\"\";\n" +
+ " @SuppressWarnings(\"nls\")\n" +
+ " void foo() {\n" +
+ " String x2 = \"\"\"\n" +
+ " abcdefg\n" +
+ " hijklmn\n" +
+ " \"\"\";\n" +
+ " }\n" +
+ "}"
+ },
+ null,
+ customOptions,
+ "----------\n" +
+ "1. WARNING in X.java (at line 3)\n" +
+ " String x = \"\"\"\n" +
+ " abcdefg\n" +
+ " hijklmn\n" +
+ " \"\"\";\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Non-externalized string literal; it should be followed by //$NON-NLS-<n>$\n" +
+ "----------\n",
+ JAVAC_OPTIONS);
+}
+public void test004() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+ this.runNegativeTest(
+ true,
+ new String[] {
+ "X.java",
+ "class X {\n" +
+ "\n" +
+ " void foo() {\n" +
+ " String s6 = \"\"\"\n" +
+ " SUCCESS\n" +
+ " \"\"\";\n" +
+ " System.out.println(s6);\n" +
+ " }\n" +
+ "}",
+ },
+ null, customOptions,
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " String s6 = \"\"\"\n" +
+ " SUCCESS\n" +
+ " \"\"\";\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Non-externalized string literal; it should be followed by //$NON-NLS-<n>$\n" +
+ "----------\n",
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
+}
+public void test005() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.WARNING);
+ customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " String s6 = \"\"\"\n" +
+ " SUCCESS\n" +
+ " \"\"\"; //$NON-NLS-1$\n" +
+ " System.out.println(s6);\n" +
+ " }\n" +
+ "}",
+ },
+ "SUCCESS",
+ null,
+ true,
+ null,
+ customOptions,
+ null);
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=237245
+public void test006() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+ customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " @Annot({\n" +
+ " @A(name = \"\"\"\n" +
+ " name\n" +
+ " \"\"\", //$NON-NLS-1$\n" +
+ " value = \"\"\"\n" +
+ " Test\n" +
+ " \"\"\") //$NON-NLS-1$\n" +
+ " })\n" +
+ " @X2(\"\"\"\n" +
+ " \"\"\") //$NON-NLS-1$\n" +
+ " void foo() {\n" +
+ " }\n" +
+ "}\n" +
+ "@interface Annot {\n" +
+ " A[] value();\n" +
+ "}\n" +
+ "@interface A {\n" +
+ " String name();\n" +
+ " String value();\n" +
+ "}\n" +
+ "@interface X2 {\n" +
+ " String value();\n" +
+ "}",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " \"\"\", //$NON-NLS-1$\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "Unnecessary $NON-NLS$ tag\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " \"\"\") //$NON-NLS-1$\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "Unnecessary $NON-NLS$ tag\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 11)\n" +
+ " \"\"\") //$NON-NLS-1$\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "Unnecessary $NON-NLS$ tag\n" +
+ "----------\n",
+ null,
+ true,
+ customOptions);
+}
+public static Class testClass() {
+ return ExternalizeStringLiteralsTest_15.class;
+}
+}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiterals15Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_1_5.java
index bc8501f0b..31cc9e40e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiterals15Test.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_1_5.java
@@ -21,14 +21,14 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
@SuppressWarnings({ "unchecked", "rawtypes" })
-public class ExternalizeStringLiterals15Test extends AbstractRegressionTest {
+public class ExternalizeStringLiteralsTest_1_5 extends AbstractRegressionTest {
static {
// TESTS_NAMES = new String[] { "test000" };
// TESTS_NUMBERS = new int[] { 7 };
// TESTS_RANGE = new int[] { 11, -1 };
}
-public ExternalizeStringLiterals15Test(String name) {
+public ExternalizeStringLiteralsTest_1_5(String name) {
super(name);
}
public static Test suite() {
@@ -274,6 +274,6 @@ public void test007() {
customOptions);
}
public static Class testClass() {
- return ExternalizeStringLiterals15Test.class;
+ return ExternalizeStringLiteralsTest_1_5.class;
}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
index 993234735..e0a02bc54 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
@@ -576,6 +576,7 @@ public class RecordsRestrictedClassTest extends AbstractRegressionTest {
"----------\n");
}
public void testBug550750_025() {
+ getPossibleComplianceLevels();
this.runNegativeTest(
new String[] {
"X.java",
@@ -602,9 +603,15 @@ public class RecordsRestrictedClassTest extends AbstractRegressionTest {
" record Point(int myInt, int myZ, int myZ) implements I {\n" +
" ^^^\n" +
"Duplicate component myZ in record\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 6)\n" +
+ " record Point(int myInt, int myZ, int myZ) implements I {\n" +
+ " ^^^\n" +
+ "Duplicate parameter myZ\n" +
"----------\n");
}
public void testBug550750_026() {
+ getPossibleComplianceLevels();
this.runNegativeTest(
new String[] {
"X.java",
@@ -634,8 +641,18 @@ public class RecordsRestrictedClassTest extends AbstractRegressionTest {
"----------\n" +
"3. ERROR in X.java (at line 6)\n" +
" record Point(int myInt, int myInt, int myInt, int myZ) implements I {\n" +
+ " ^^^^^\n" +
+ "Duplicate parameter myInt\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 6)\n" +
+ " record Point(int myInt, int myInt, int myInt, int myZ) implements I {\n" +
" ^^^^^\n" +
"Duplicate component myInt in record\n" +
+ "----------\n" +
+ "5. ERROR in X.java (at line 6)\n" +
+ " record Point(int myInt, int myInt, int myInt, int myZ) implements I {\n" +
+ " ^^^^^\n" +
+ "Duplicate parameter myInt\n" +
"----------\n");
}
public void testBug550750_027() {
@@ -1112,6 +1129,7 @@ public class RecordsRestrictedClassTest extends AbstractRegressionTest {
"----------\n");
}
public void testBug553152_008() {
+ getPossibleComplianceLevels();
this.runNegativeTest(
new String[] {
"X.java",
@@ -1133,22 +1151,17 @@ public class RecordsRestrictedClassTest extends AbstractRegressionTest {
"interface I {}\n"
},
"----------\n" +
- "1. ERROR in X.java (at line 7)\n" +
- " public Point {\n" +
- " ^^^^^\n" +
- "Duplicate method Point(Integer, int) in type Point\n" +
- "----------\n" +
- "2. ERROR in X.java (at line 8)\n" +
+ "1. ERROR in X.java (at line 8)\n" +
" this.myInt = 0;\n" +
" ^^^^^^^^^^\n" +
"Illegal explicit assignment of a final field myInt in compact constructor\n" +
"----------\n" +
- "3. ERROR in X.java (at line 9)\n" +
+ "2. ERROR in X.java (at line 9)\n" +
" this.myZ = 0;\n" +
" ^^^^^^^^\n" +
"Illegal explicit assignment of a final field myZ in compact constructor\n" +
"----------\n" +
- "4. ERROR in X.java (at line 11)\n" +
+ "3. ERROR in X.java (at line 11)\n" +
" public Point(Integer myInt, int myZ) {\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Duplicate method Point(Integer, int) in type Point\n" +
@@ -7361,6 +7374,7 @@ public void testBug563182_01() {
//Test that in presence of an explicit canonical constructor that is NOT annotated with @SafeVarargs,
// we don't report the warning on the record type but report on the explicit canonical constructor
public void testBug563182_02() {
+ getPossibleComplianceLevels();
Map<String, String> customOptions = getCompilerOptions();
this.runNegativeTest(
new String[] {
@@ -7388,6 +7402,7 @@ public void testBug563182_02() {
//Test that in presence of an explicit canonical constructor that IS annotated with @SafeVarargs,
//we don't report the warning on neither the record type nor the explicit canonical constructor
public void testBug563182_03() {
+ getPossibleComplianceLevels();
Map<String, String> customOptions = getCompilerOptions();
this.runNegativeTest(
new String[] {
@@ -7437,6 +7452,7 @@ public void testBug563182_04() {
//Test that in presence of a compact canonical constructor that IS annotated with @SafeVarargs,
//we don't report the warning on neither the record type nor the compact canonical constructor
public void testBug563182_05() {
+ getPossibleComplianceLevels();
Map<String, String> customOptions = getCompilerOptions();
this.runNegativeTest(
new String[] {
@@ -8992,6 +9008,7 @@ public void testBug572934_003() {
options.put(CompilerOptions.OPTION_ReportSpecialParameterHidingField, CompilerOptions.DISABLED);
}
public void testBug573195_001() throws Exception {
+ getPossibleComplianceLevels();
runConformTest(
new String[] {
"X.java",
@@ -9009,19 +9026,20 @@ public void testBug573195_001() throws Exception {
},
"1");
String expectedOutput = // constructor
- " // Method descriptor #12 (I)V\n" +
+ " // Method descriptor #8 (I)V\n" +
" // Stack: 2, Locals: 2\n" +
- " protected X$R(int arg0);\n" +
+ " protected X$R(int i);\n" +
" 0 aload_0 [this]\n" +
- " 1 invokespecial java.lang.Record() [36]\n" +
+ " 1 invokespecial java.lang.Record() [10]\n" +
" 4 aload_0 [this]\n" +
- " 5 iload_1 [arg0]\n" +
- " 6 putfield X$R.i : int [20]\n" +
+ " 5 iload_1 [i]\n" +
+ " 6 putfield X$R.i : int [13]\n" +
" 9 return\n";
RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "X$R.class", ClassFileBytesDisassembler.SYSTEM);
}
public void testBug574284_001() throws Exception {
+ getPossibleComplianceLevels();
runConformTest(
new String[] {
"X.java",
@@ -9042,17 +9060,17 @@ public void testBug574284_001() throws Exception {
},
"0");
String expectedOutput = // constructor
- " // Method descriptor #14 (Z[I)V\n" +
+ " // Method descriptor #10 (Z[I)V\n" +
" // Stack: 2, Locals: 3\n" +
- " X$Rec(boolean arg0, int... arg1);\n" +
+ " X$Rec(boolean isHidden, int... indexes);\n" +
" 0 aload_0 [this]\n" +
- " 1 invokespecial java.lang.Record() [41]\n" +
+ " 1 invokespecial java.lang.Record() [12]\n" +
" 4 aload_0 [this]\n" +
- " 5 iload_1 [arg0]\n" +
- " 6 putfield X$Rec.isHidden : boolean [21]\n" +
+ " 5 iload_1 [isHidden]\n" +
+ " 6 putfield X$Rec.isHidden : boolean [15]\n" +
" 9 aload_0 [this]\n" +
- " 10 aload_2 [arg1]\n" +
- " 11 putfield X$Rec.indexes : int[] [24]\n" +
+ " 10 aload_2 [indexes]\n" +
+ " 11 putfield X$Rec.indexes : int[] [17]\n" +
" 14 return\n";
RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "X$Rec.class", ClassFileBytesDisassembler.SYSTEM);
@@ -9173,4 +9191,36 @@ public void testBug576806_001() {
false,
options);
}
+
+public void testIssue365_001() throws Exception {
+ getPossibleComplianceLevels();
+ runConformTest(
+ new String[] {
+ "A.java",
+ "import java.util.Collections;\n" +
+ "import java.util.List;\n" +
+ "public record A(List<String> names) {\n" +
+ " public A(String name) {\n" +
+ " this(Collections.singletonList(name));\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(0);\n" +
+ " }" +
+ "}\n"
+ },
+ "0");
+ String expectedOutput = // constructor
+ " // Method descriptor #10 (Ljava/util/List;)V\n" +
+ " // Signature: (Ljava/util/List<Ljava/lang/String;>;)V\n" +
+ " // Stack: 2, Locals: 2\n" +
+ " public A(java.util.List names);\n" +
+ " 0 aload_0 [this]\n" +
+ " 1 invokespecial java.lang.Record() [13]\n" +
+ " 4 aload_0 [this]\n" +
+ " 5 aload_1 [names]\n" +
+ " 6 putfield A.names : java.util.List [16]\n" +
+ " 9 return\n";
+ RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "A.class", ClassFileBytesDisassembler.SYSTEM);
+
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
index 4445a9858..40b0186cc 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
@@ -118,7 +118,7 @@ public static Test suite() {
since_1_5.add(BatchCompilerTest.class);
since_1_5.add(NullAnnotationBatchCompilerTest.class);
since_1_5.add(ConcurrentBatchCompilerTest.class);
- since_1_5.add(ExternalizeStringLiterals15Test.class);
+ since_1_5.add(ExternalizeStringLiteralsTest_1_5.class);
since_1_5.add(Deprecated15Test.class);
since_1_5.add(InnerEmulationTest_1_5.class);
since_1_5.add(AssignmentTest_1_5.class);
@@ -210,6 +210,7 @@ public static Test suite() {
since_15.add(Unicode13Test.class);
since_15.add(BatchCompilerTest_15.class);
since_15.add(TextBlockTest.class);
+ since_15.add(ExternalizeStringLiteralsTest_15.class);
// add 16 specific test here (check duplicates)
ArrayList since_16 = new ArrayList();
diff --git a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
index dbb452b27..e3402e3a1 100644
--- a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.core.tests.model;singleton:=true
-Bundle-Version: 3.11.400.qualifier
+Bundle-Version: 3.11.600.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.jdt.core.tests,
diff --git a/org.eclipse.jdt.core.tests.model/pom.xml b/org.eclipse.jdt.core.tests.model/pom.xml
index a0c04d431..ac0fc3b83 100644
--- a/org.eclipse.jdt.core.tests.model/pom.xml
+++ b/org.eclipse.jdt.core.tests.model/pom.xml
@@ -15,11 +15,11 @@
<parent>
<artifactId>tests-pom</artifactId>
<groupId>org.eclipse.jdt</groupId>
- <version>4.27.0-SNAPSHOT</version>
+ <version>4.28.0-SNAPSHOT</version>
<relativePath>../tests-pom/</relativePath>
</parent>
<artifactId>org.eclipse.jdt.core.tests.model</artifactId>
- <version>3.11.400-SNAPSHOT</version>
+ <version>3.11.600-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
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 33bc581fe..2ca29d14a 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
@@ -693,6 +693,9 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance) throws CoreException, IOException {
addLibrary(javaProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance, null);
}
+ protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance, boolean exported) throws CoreException, IOException {
+ addLibrary(javaProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance, null, exported);
+ }
protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String[] nonJavaResources, String compliance) throws CoreException, IOException {
addLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, null, null, compliance, null);
}
@@ -720,6 +723,19 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
String[] librariesExclusionPatterns,
String compliance,
Map options) throws CoreException, IOException {
+ addLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, librariesInclusionPatterns, librariesExclusionPatterns, compliance, options, true);
+ }
+ private void addLibrary(
+ IJavaProject javaProject,
+ String jarName,
+ String sourceZipName,
+ String[] pathAndContents,
+ String[] nonJavaResources,
+ String[] librariesInclusionPatterns,
+ String[] librariesExclusionPatterns,
+ String compliance,
+ Map options,
+ boolean exported) throws CoreException, IOException {
IProject project = createLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, compliance, options);
String projectPath = '/' + project.getName() + '/';
addLibraryEntry(
@@ -729,7 +745,7 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
null,
toIPathArray(librariesInclusionPatterns),
toIPathArray(librariesExclusionPatterns),
- true
+ exported
);
}
protected IProject createLibrary(
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests11.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests11.java
index b34ad053a..b2b70d19d 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests11.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests11.java
@@ -17,6 +17,9 @@ import org.eclipse.jdt.core.JavaModelException;
import junit.framework.Test;
public class CompletionTests11 extends AbstractJavaModelCompletionTests {
+ static {
+ // TESTS_NAMES = new String[] {};
+ }
public CompletionTests11(String name) {
super(name);
@@ -58,4 +61,190 @@ public void test_var_in_parameter_in_lambda() throws JavaModelException {
requestor.getResults());
}
+public void test_members_matching_paramater_name_on_getter() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/Smart.java",
+ "package test;\n" +
+ "public class Smart {\n" +
+ " public static void persist(Task task) { \n" +
+ " create(task.);\n" +
+ " }\n" +
+ " public static void create(String name, boolean completed, int details) {}\n" +
+ " public static class Task {\n" +
+ " public String getName() {return null;}\n" +
+ " public boolean isCompleted() {return false;}\n" +
+ " public String details() {return null;}\n" +
+ " }\n" +
+ "}\n");
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "task.";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertTrue(requestor.getResults(), requestor.getResults()
+ .contains("getName[METHOD_REF]{getName(), Ltest.Smart$Task;, ()Ljava.lang.String;, getName, null, " +
+ (R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_CASE + R_CASE + R_EXACT_EXPECTED_TYPE
+ + R_NON_STATIC + R_NON_RESTRICTED + R_RESOLVED)
+ + "}"));
+}
+
+public void test_members_matching_paramater_name_on_non_getter() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/Smart.java",
+ "package test;\n" +
+ "public class Smart {\n" +
+ " public static void persist(Task task) { \n" +
+ " create(task.getName(), false, task.);\n" +
+ " }\n" +
+ " public static void create(String name, boolean completed, String details, String assignee) {}\n"
+ +
+ " public static class Task {\n" +
+ " public String getName() {return null;}\n" +
+ " public boolean isCompleted() {return false;}\n" +
+ " public String details() {return null;}\n" +
+ " public int getAssignee() {return null;}\n" +
+ " }\n" +
+ "}\n");
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "task.";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertTrue(requestor.getResults(), requestor.getResults()
+ .contains("details[METHOD_REF]{details(), Ltest.Smart$Task;, ()Ljava.lang.String;, details, null, " +
+ (R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_CASE + R_CASE + R_EXACT_EXPECTED_TYPE
+ + R_NON_STATIC + R_NON_RESTRICTED + R_RESOLVED)
+ + "}"));
+}
+
+public void test_members_matching_paramater_name_on_boolean_getter() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/Smart.java",
+ "package test;\n" +
+ "public class Smart {\n" +
+ " public static void persist(Task task) { \n" +
+ " create(task.getName(), task.);\n" +
+ " }\n" +
+ " public static void create(String name, boolean completed, String details, String assignee) {}\n"
+ +
+ " public static class Task {\n" +
+ " public String getName() {return null;}\n" +
+ " public boolean isCompleted() {return false;}\n" +
+ " public String details() {return null;}\n" +
+ " public int getAssignee() {return null;}\n" +
+ " }\n" +
+ "}\n");
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "task.";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertTrue(requestor.getResults(), requestor.getResults()
+ .contains(
+ "isCompleted[METHOD_REF]{isCompleted(), Ltest.Smart$Task;, ()Z, isCompleted, null, "
+ +
+ (R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_CASE + R_CASE + R_EXACT_EXPECTED_TYPE
+ + R_NON_STATIC + R_NON_RESTRICTED + R_RESOLVED)
+ + "}"));
+}
+
+public void test_members_matching_paramater_name_on_wrong_type() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/Smart.java",
+ "package test;\n" +
+ "public class Smart {\n" +
+ " public static void persist(Task task) { \n" +
+ " create(task.getName(), false, \"\", task.);\n" +
+ " }\n" +
+ " public static void create(String name, boolean completed, String details, String assignee) {}\n"
+ +
+ " public static class Task {\n" +
+ " public String getName() {return null;}\n" +
+ " public boolean isCompleted() {return false;}\n" +
+ " public String details() {return null;}\n" +
+ " public int getAssignee() {return null;}\n" +
+ " }\n" +
+ "}\n");
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "task.";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertFalse(requestor.getResults(), requestor.getResults()
+ .contains(
+ "getAssignee[METHOD_REF]{getAssignee(), Ltest.Smart$Task;, ()Ljava.lang.String;, getAssignee, null, "
+ +
+ (R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_EXACT_EXPECTED_TYPE + R_NON_STATIC
+ + R_NON_RESTRICTED + R_RESOLVED)
+ + "}"));
+}
+
+public void test_members_matching_paramater_name_on_field() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/Smart.java",
+ "package test;\n" +
+ "public class Smart {\n" +
+ " public static void persist(Task task) { \n" +
+ " create(task.getName(), false, \"\", task.);\n" +
+ " }\n" +
+ " public static void create(String name, boolean completed, String details, String assignee) {}\n"
+ +
+ " public static class Task {\n" +
+ " public String getName() {return null;}\n" +
+ " public boolean isCompleted() {return false;}\n" +
+ " public String details() {return null;}\n" +
+ " public int getAssignee() {return null;}\n" +
+ " public String assignee;}\n" +
+ " }\n" +
+ "}\n");
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "task.";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertTrue(requestor.getResults(), requestor.getResults()
+ .contains(
+ "assignee[FIELD_REF]{assignee, Ltest.Smart$Task;, Ljava.lang.String;, assignee, null, "
+ +
+ (R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_CASE + R_CASE + R_EXACT_EXPECTED_TYPE
+ + R_NON_STATIC + R_NON_RESTRICTED + R_RESOLVED)
+ + "}"));
+}
+
+public void test_members_matching_paramater_name_on_local_variable() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/Smart.java",
+ "package test;\n" +
+ "public class Smart {\n" +
+ " public static void persist(String name, String shortName) { \n" +
+ " create(null, false, null, null);\n" +
+ " }\n" +
+ " public static void create(String name, boolean completed, String details, String assignee) {}\n"
+ +
+ "}\n");
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "create(";
+ int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertTrue(requestor.getResults(), requestor.getResults()
+ .contains(
+ "name[LOCAL_VARIABLE_REF]{name, null, Ljava.lang.String;, name, null, "
+ +
+ (R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_CASE + R_NON_STATIC + R_NON_RESTRICTED
+ + R_UNQUALIFIED)
+ + "}"));
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
index 5ab2d775f..864669cef 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
@@ -6753,4 +6753,50 @@ public void testGH583_onArrayCreationSupplier_expectNewMethodRefCompletions() th
assertTrue(String.format("Result doesn't contain expected methods (%s)", result),
result.contains("new[KEYWORD]{new, null, null, new, null, 49}"));
}
+// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/767
+public void testGH767() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/Foo.java",
+ "public class Foo {\n"
+ + " public void foo() {\n"
+ + " \"abc\".substring(i)."
+ + " }\n"
+ + "}");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "substring(i).";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner, new NullProgressMonitor());
+
+ String result = requestor.getResults();
+ assertTrue(String.format("Result doesn't contain expected method (%s)", result),
+ result.contains("length[METHOD_REF]{length(), Ljava.lang.String;, ()I, length, null, 60}\n"));
+}
+// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/831
+public void testIntersection18GH831() throws Exception {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/Foo.java",
+ "public class Foo {\n"
+ + " public void foo() {\n"
+ + " java.util.Optional.of(true ? 0 : \"\")."
+ + " }\n"
+ + "}");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "of(true ? 0 : \"\").";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner, new NullProgressMonitor());
+
+ String result = requestor.getResults();
+ assertTrue(String.format("Result doesn't contain expected method (%s)", result),
+ result.contains("get[METHOD_REF]{get(), Ljava.util.Optional<Ljava.io.Serializable;>;, ()Ljava.io.Serializable;, get, null, 60}\n"));
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs16Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs16Tests.java
index 8123f7832..ba6ade14b 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs16Tests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs16Tests.java
@@ -16,9 +16,11 @@ import java.io.IOException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.ILocalVariable;
+import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.search.IJavaSearchScope;
@@ -621,6 +623,44 @@ public class JavaSearchBugs16Tests extends AbstractJavaSearchTests {
}
}
+
+ /*
+ * A record defined in a JRE class causes an AIOOBE during a call hierarchy computation.
+ * The record is encountered while indexing a Java project with a snippet,
+ * when computing the call hierarchy of a field in the snippet.
+ * The same AIOOBE can be reproduced with a reference search in the same snippet.
+ * https://github.com/eclipse-jdt/eclipse.jdt.core/issues/790
+ */
+ public void testAIOOBEForRecordClassGh790() throws Exception {
+ String testProjectName = "gh790AIOOBEForRecordClass";
+ try {
+ IJavaProject project = createJava16Project(testProjectName, new String[] {"src"});
+ String packageFolder = "/" + testProjectName + "/src/test";
+ createFolder(packageFolder);
+ String testSource =
+ "package test;\n" +
+ "public class Test {\n" +
+ "protected final java.util.HashMap<?, ?> internal;\n" +
+ "protected final java.util.HashMap<?, ?> map;\n" +
+ " public Test() {\n" +
+ " internal = new java.util.HashMap<>();\n" +
+ " map = internal;\n" +
+ " }\n" +
+ "}\n";
+ createFile(packageFolder + "/Test.java", testSource);
+ buildAndExpectNoProblems(project);
+
+ IType type = project.findType("test.Test");
+ IField field = type.getField("internal");
+ search(field, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults(
+ "src/test/Test.java test.Test() [internal] EXACT_MATCH\n" +
+ "src/test/Test.java test.Test() [internal] EXACT_MATCH");
+ } finally {
+ deleteProject(testProjectName);
+ }
+ }
+
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
index e7c98ee78..7ecabdae7 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
@@ -15422,7 +15422,7 @@ public void testMethodReferenceAfterCompileErrorBugGh438() throws Exception {
}
/*
- * Test that having a module conflict in projects that are on the compile classpath
+ * Test that having a module conflict in libraries that are on the compile classpath
* (and not the compile module path) doesn't affect searching for types in those projects.
* https://github.com/eclipse-jdt/eclipse.jdt.core/issues/675
*/
@@ -15482,6 +15482,82 @@ public void testModuleConflictForClasspathProjectsBugGh675() throws Exception {
}
}
+/**
+ * A modular project refers to a modular library defining a type {@code TestClass},
+ * this project also references a non-modular project on its classpath.
+ * The non-modular project uses a non-modular library that defines the same type {@code TestClass}.
+ * Since neither project exports the library, there is no compile error and no module conflict for the type.
+ * This test ensures the search doesn't run into a module conflict due to not considering whether the libraries are exported.
+ *
+ * Originally the problem was observed by using a Java 8 project and a Java 11 project,
+ * with {@code java.util.Locale} as the type that causes the search to run into a module conflict.
+ *
+ * https://github.com/eclipse-jdt/eclipse.jdt.core/issues/723
+ */
+public void testModuleConflictGh723() throws Exception {
+ String projectName = "gh723Project";
+ String modularProjectName = "gh723ProjectModular";
+ try {
+ IJavaProject project = createJavaProject(projectName, new String[] {"src"}, new String[] {"JCL11_LIB"}, "bin", "11");
+ IJavaProject modularProject = createJavaProject(modularProjectName, new String[] {"src"}, new String[] {"JCL11_LIB"}, "bin", "11");
+
+ createFolder("/" + projectName + "/src/test/");
+ createFile("/" + projectName + "/src/test/Test.java",
+ "package test;\n" +
+ "public class Test {\n" +
+ " public static void test(testpackage.TestClass t) {\n" +
+ " }\n" +
+ "}");
+
+ createFolder("/" + modularProjectName + "/src/testmodular/");
+ createFile("/" + modularProjectName + "/src/testmodular/TestModular.java",
+ "package testmodular;\n" +
+ "public class TestModular {\n" +
+ " public void testModular() {\n" +
+ " test.Test.test(null);\n" +
+ " }\n" +
+ "}");
+
+ String ambiguousTypeDefinition =
+ "package testpackage;\n" +
+ "public class TestClass {\n" +
+ "}";
+
+ addLibrary(project,
+ "libGh723.jar",
+ "libGh723.src.zip",
+ new String[] {
+ "testpackage/TestClass.java",
+ ambiguousTypeDefinition },
+ JavaCore.VERSION_1_8,
+ false);
+
+ addModularLibrary(modularProject,
+ "libGh723_modular.jar",
+ "libGh723_modular.src.zip",
+ new String[] {
+ "module-info.java",
+ "module testmodule {\n" +
+ " exports testpackage;\n" +
+ "}",
+ "testpackage/TestClass.java",
+ ambiguousTypeDefinition },
+ JavaCore.VERSION_11);
+
+ addClasspathEntry(modularProject, JavaCore.newProjectEntry(project.getPath()));
+ buildAndExpectNoProblems(project, modularProject);
+
+ IType type = project.findType("test.Test");
+ IMethod method = type.getMethod("test", new String [] {"Qtestpackage.TestClass;"});
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ assertSearchResults(
+ "src/testmodular/TestModular.java void testmodular.TestModular.testModular() [test(null)] EXACT_MATCH");
+ } finally {
+ deleteProject(projectName);
+ deleteProject(modularProjectName);
+ }
+}
+
private static String toString(char[][] modules) {
StringBuilder sb = new StringBuilder();
for (char[] m : modules) {
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 470c02045..2b81638d6 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
@@ -40,8 +40,10 @@ import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
@@ -2835,6 +2837,65 @@ public class JavaSearchBugsTests2 extends AbstractJavaSearchTests {
}
}
+ /**
+ * Test that a diamond in a type name doesn't result in an AIOOBE during a search.
+ * See: https://github.com/eclipse-jdt/eclipse.jdt.core/issues/825
+ */
+ public void testOutOfBoundsIndexExceptionDuringSearchGh825() throws Exception {
+ String projectName = "testGh825";
+ try {
+ IJavaProject project = createJavaProject(projectName, new String[] {"src"}, new String[] {"JCL11_LIB"}, "bin", "11");
+ String srcFolder = "/" + projectName + "/src/";
+ String packageFolder = srcFolder + "test";
+ createFolder(packageFolder);
+ String snippet = String.join(System.lineSeparator(), new String[] {
+ "package test;",
+ "public class Test {",
+ " public interface TestInterface<T> {",
+ " void testMethod(T t);",
+ " }",
+ " TestInterface<String> SUP = new TestInterface<>() {",
+ " public void testMethod(String s) {}",
+ " };",
+ " static void shouldFail() {}",
+ "}",
+ });
+ createFile(packageFolder + "/Test.java", snippet);
+
+ String module = "module tester {}";
+ createFile(srcFolder + "/module-info.java", module);
+
+ String testFolder = "/" + projectName + "/test";
+ createFolder(testFolder);
+ IClasspathAttribute[] testAttrs = { JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, Boolean.toString(true)) };
+ addClasspathEntry(project, JavaCore.newSourceEntry(
+ new Path(testFolder),
+ null,
+ null,
+ new Path("/" + projectName + "/bin-test"),
+ testAttrs));
+
+ addLibrary(project,
+ "libGh825.jar",
+ "libGh825.src.zip",
+ new String[] {
+ "testpackage/TestClass.java",
+ "package testpackage;\n" +
+ "public class TestClass {}"
+ },
+ JavaCore.VERSION_11);
+
+ buildAndExpectNoProblems(project);
+ IType type = project.findType("test.Test");
+ IMethod method = type.getMethod("shouldFail", new String[0]);
+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+ // we expect no matches and no exceptions
+ assertSearchResults("");
+ } finally {
+ deleteProject(projectName);
+ }
+ }
+
private static void printJavaElements(IJavaProject javaProject, PrintStream output) throws Exception {
output.println("Printing Java elements of Java project: " + javaProject);
List<IJavaElement> queue = new LinkedList<>();
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 c7811cbac..3e3f73d9f 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
@@ -5604,7 +5604,7 @@ public class ModuleBuilderTests extends ModifyingResourceTests {
try {
IClasspathAttribute[] attributes = {
JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"),
- JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "java.desktop=/missing.path::java.base=/org.astro.patch/src:/org.astro.patch/src2")
+ JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "java.desktop=/missing.path::java.base=/org.astro.patch/src"+File.pathSeparator+"/org.astro.patch/src2")
};
IJavaProject patchProject = createJava9ProjectWithJREAttributes("org.astro.patch", new String[]{"src", "src2"}, attributes);
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
index b6d7e883f..2d8c4b2c2 100644
--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true
-Bundle-Version: 3.33.0.OTDT_r282_qualifier
+Bundle-Version: 3.33.100.OTDT_r282_qualifier
Bundle-Activator: org.eclipse.jdt.core.JavaCore
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -52,7 +52,7 @@ Require-Bundle: org.eclipse.core.resources;bundle-version="[3.18.0,4.0.0)",
org.eclipse.core.filesystem;bundle-version="[1.7.0,2.0.0)",
org.eclipse.text;bundle-version="[3.6.0,4.0.0)",
org.eclipse.team.core;bundle-version="[3.1.0,4.0.0)";resolution:=optional,
- org.eclipse.jdt.core.compiler.batch;bundle-version="3.33.0.OTDT_r282";visibility:=reexport
+ org.eclipse.jdt.core.compiler.batch;bundle-version="3.33.100.OTDT_r282";visibility:=reexport
Bundle-RequiredExecutionEnvironment: JavaSE-11
Eclipse-ExtensibleAPI: true
Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index d54d61793..5cde37727 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -25,13 +25,15 @@ package org.eclipse.jdt.internal.codeassist;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.StreamSupport;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -261,7 +263,7 @@ import org.eclipse.jdt.internal.core.SourceMethodElementInfo;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
-import org.eclipse.jdt.internal.core.search.matching.IndexBasedJavaSearchEnvironment;
+import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.Util;
import org.eclipse.objectteams.otdt.core.IOTType;
@@ -501,8 +503,7 @@ public final class CompletionEngine
//{ObjectTeams: prefixes for callout-to-field:
private static final char[] SET = "set".toCharArray(); //$NON-NLS-1$
-
- private static final char[] GET = "get".toCharArray(); //$NON-NLS-1$
+ // GET is declared below (regular JDT)
// SH}
public static char[] createBindingKey(char[] packageName, char[] typeName) {
@@ -722,6 +723,8 @@ public final class CompletionEngine
createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
private final static char[] JAVA_LANG_NAME =
CharOperation.concatWith(JAVA_LANG, '.');
+ private final static char[] GET = "get".toCharArray(); //$NON-NLS-1$
+ private final static char[] IS = "is".toCharArray(); //$NON-NLS-1$
private final static int NONE = 0;
private final static int SUPERTYPE = 1;
@@ -5022,16 +5025,28 @@ public final class CompletionEngine
}
return 0;
}
- int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
- if(CharOperation.equals(token, proposalName, true)) {
+
+ int computeRelevanceForCaseMatching(char[][] tokens, char[] proposalName) {
+ int finalRelevance = 0;
+ for (int i = 0; i < tokens.length; i++) {
+ int relevance = computeRelevanceForCaseMatching(tokens[i], proposalName);
+ if (relevance > finalRelevance) {
+ finalRelevance = relevance;
+ }
+ }
+ return finalRelevance;
+ }
+
+ int computeRelevanceForCaseMatching(char[] token, char[] proposalName) {
+ if (CharOperation.equals(token, proposalName, true)) {
return R_EXACT_NAME + R_CASE;
- } else if(CharOperation.equals(token, proposalName, false)) {
+ } else if (CharOperation.equals(token, proposalName, false)) {
return R_EXACT_NAME;
} else if (CharOperation.prefixEquals(token, proposalName, false)) {
if (CharOperation.prefixEquals(token, proposalName, true))
return R_CASE;
- } else if (this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, proposalName)){
- return R_CAMEL_CASE;
+ } else if (this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, proposalName)) {
+ return R_CAMEL_CASE;
} else if (this.options.substringMatch && CharOperation.substringMatch(token, proposalName)) {
return R_SUBSTRING;
} else if (this.options.subwordMatch && CharOperation.subWordMatch(token, proposalName)) {
@@ -7303,6 +7318,9 @@ public final class CompletionEngine
}
}
}
+
+ char[] boostMatches = findParameterNameAtLocationFromAssistParent(new ObjectVector());
+
// Inherited fields which are hidden by subclasses are filtered out
// No visibility checks can be performed without the scope & invocationSite
@@ -7481,6 +7499,9 @@ public final class CompletionEngine
relevance += computeRelevanceForResolution();
relevance += computeRelevanceForInterestingProposal(field);
relevance += computeRelevanceForCaseMatching(fieldName, field.name);
+ if(boostMatches.length > 0) {
+ relevance += computeRelevanceForCaseMatching(boostMatches, field.name);
+ }
int computeRelevanceForExpectingType = computeRelevanceForExpectingType(field.type);
if(this.strictMatchForExtepectedType && computeRelevanceForExpectingType <= 0) {
continue;
@@ -9875,6 +9896,14 @@ public final class CompletionEngine
int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
int minArgLength = argTypes == null ? 0 : argTypes.length;
+ char[][] boostMatches = new char[0][];
+ char[] parameterName = findParameterNameAtLocationFromAssistParent(new ObjectVector());
+ if(parameterName.length > 0) {
+ char[] nameForMethods = capitalize(parameterName);
+ boostMatches = new char[][] { parameterName, CharOperation.concat(GET, nameForMethods),
+ CharOperation.concat(IS, nameForMethods) };
+ }
+
next : for (int f = methods.length; --f >= 0;) {
MethodBinding method = methods[f];
@@ -10128,6 +10157,9 @@ public final class CompletionEngine
relevance += computeRelevanceForResolution();
relevance += computeRelevanceForInterestingProposal();
relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+ if(boostMatches.length > 0) {
+ relevance += computeRelevanceForCaseMatching(boostMatches, method.selector);
+ }
int computeRelevanceForExpectingType = computeRelevanceForExpectingType(method.returnType);
if(this.strictMatchForExtepectedType && computeRelevanceForExpectingType <= 0) {
continue;
@@ -10292,6 +10324,55 @@ public final class CompletionEngine
methodsFound.addAll(newMethodsFound);
}
+
+ private char[] capitalize(char[] name) {
+ char[] result = new char[name.length];
+ for (int i = 0; i < name.length; i++) {
+ if (i == 0) {
+ result[i] = Character.toUpperCase(name[i]);
+ } else {
+ result[i] = name[i];
+ }
+ }
+ return result;
+ }
+
+ private char[] findParameterNameAtLocationFromAssistParent(ObjectVector methodsFound) {
+ char[] parameterName = new char[0];
+ MethodBinding[] candidates;
+ final MessageSend parent;
+ if (this.parser.assistNodeParent instanceof MessageSend) {
+ parent = (MessageSend) this.parser.assistNodeParent;
+ candidates = Optional.ofNullable(parent.actualReceiverType)
+ .or(() -> Optional.ofNullable(parent.receiver).map(r -> r.resolvedType))
+ .map(t -> t.getMethods(parent.selector)).orElse(new MethodBinding[0]);
+ } else if (this.parser.assistNode instanceof MessageSend) {
+ parent = (MessageSend) this.parser.assistNode;
+ candidates = StreamSupport.stream(methodsFound.spliterator(), false)
+ .filter(Objects::nonNull)
+ .filter(o -> o instanceof Object[]).map(o -> (Object[]) o)
+ .map(o -> o[0]).filter(o -> o instanceof MethodBinding).map(b -> (MethodBinding) b)
+ .filter(b -> CharOperation.equals(parent.selector, b.selector)).findFirst()
+ .map(m -> new MethodBinding[] { m }).orElse(new MethodBinding[0]);
+ } else {
+ return parameterName;
+ }
+
+ final int argumentLength = (parent.arguments != null) ? parent.arguments.length : 1;
+ for (MethodBinding binding : candidates) {
+ if (binding.parameterNames.length >= argumentLength) {
+ for (int i = 0; i < argumentLength; i++) {
+ if (parent.arguments == null || parent.arguments[i] == this.parser.assistNode) {
+ parameterName = binding.parameterNames[i];
+ }
+ }
+ }
+ if (parameterName.length > 0) {
+ break;
+ }
+ }
+ return parameterName;
+ }
private void findLocalMethodsFromFavorites(
char[] methodName,
MethodBinding[] methods,
@@ -13896,6 +13977,8 @@ public final class CompletionEngine
Scope currentScope = scope;
+ char[] boostMatches = findParameterNameAtLocationFromAssistParent(methodsFound);
+
if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
@@ -13975,6 +14058,9 @@ public final class CompletionEngine
relevance += computeRelevanceForResolution();
relevance += computeRelevanceForInterestingProposal(local);
relevance += computeRelevanceForCaseMatching(token, local.name);
+ if(boostMatches.length > 0) {
+ relevance += computeRelevanceForCaseMatching(boostMatches, local.name);
+ }
int computeRelevanceForExpectingType = computeRelevanceForExpectingType(local.type);
if(this.strictMatchForExtepectedType && computeRelevanceForExpectingType <= 0) {
continue;
@@ -14274,7 +14360,7 @@ public final class CompletionEngine
private INameEnvironment getNoCacheNameEnvironment() {
if (this.noCacheNameEnvironment == null) {
JavaModelManager.getJavaModelManager().cacheZipFiles(this);
- this.noCacheNameEnvironment = IndexBasedJavaSearchEnvironment.create(Collections.singletonList(this.javaProject), this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/));
+ this.noCacheNameEnvironment = new JavaSearchNameEnvironment(this.javaProject, this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/));
}
return this.noCacheNameEnvironment;
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
index dbb7888a8..a4d3cb43d 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
@@ -82,6 +82,9 @@ public class CompletionOnMemberAccess extends FieldReference {
ProblemMethodBinding problemMethodBinding = new ProblemMethodBinding(messageSend.selector, argBindings, ProblemReasons.NotFound);
throw new CompletionNodeFound(this, problemMethodBinding, scope);
}
+ if (messageSend.binding != null) {
+ throw new CompletionNodeFound(this, messageSend.binding.declaringClass, scope);
+ }
}
if (this.actualReceiverType == null || !this.actualReceiverType.isValidBinding())
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java
index a56925643..3b07cf141 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java
@@ -602,9 +602,12 @@ public abstract class TypeConverter {
/* rebuild identifiers and dimensions */
if (identCount == 1) { // simple type reference
if (dim == 0) {
+ int n = typeName.length;
+ boolean hasDiamond = n > 2 && typeName[n - 2] == '<' && typeName[n - 1] == '>';
char[] nameFragment;
- if (nameFragmentStart != 0 || nameFragmentEnd >= 0) {
- int nameFragmentLength = nameFragmentEnd - nameFragmentStart + 1;
+ int nameFragmentLength = nameFragmentEnd - nameFragmentStart + 1;
+ boolean hasEmptyFragment = nameFragmentLength == 0 && hasDiamond;
+ if ((nameFragmentStart != 0 || nameFragmentEnd >= 0) && !hasEmptyFragment) {
System.arraycopy(typeName, nameFragmentStart, nameFragment = new char[nameFragmentLength], 0, nameFragmentLength);
} else {
nameFragment = typeName;
@@ -618,7 +621,11 @@ public abstract class TypeConverter {
return new TypeAnchorReference(name, start);
}
// SH}
- return new SingleTypeReference(nameFragment, ((long) start << 32) + end);
+ SingleTypeReference singleTypeReference = new SingleTypeReference(nameFragment, ((long) start << 32) + end);
+ if (hasDiamond) {
+ singleTypeReference.bits |= ASTNode.IsDiamond;
+ }
+ return singleTypeReference;
} else {
int nameFragmentLength = nameFragmentEnd - nameFragmentStart + 1;
char[] nameFragment = new char[nameFragmentLength];
diff --git a/org.eclipse.jdt.core/pom.xml b/org.eclipse.jdt.core/pom.xml
index fa2d20b13..323ec7315 100644
--- a/org.eclipse.jdt.core/pom.xml
+++ b/org.eclipse.jdt.core/pom.xml
@@ -14,10 +14,10 @@
<parent>
<artifactId>eclipse.jdt.core</artifactId>
<groupId>org.eclipse.jdt</groupId>
- <version>4.27.0-SNAPSHOT</version>
+ <version>4.28.0-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jdt.core</artifactId>
- <version>3.33.0-SNAPSHOT</version>
+ <version>3.33.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<properties>
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
index 0a80f8ab9..19415b96d 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
@@ -13,13 +13,11 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core.search.indexing;
-import java.util.Collections;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CharOperation;
@@ -55,7 +53,7 @@ import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
import org.eclipse.jdt.internal.core.jdom.CompilationUnit;
-import org.eclipse.jdt.internal.core.search.matching.IndexBasedJavaSearchEnvironment;
+import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
import org.eclipse.jdt.internal.core.search.matching.MethodPattern;
import org.eclipse.jdt.internal.core.search.processing.JobManager;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
@@ -176,7 +174,7 @@ public class SourceIndexer extends AbstractIndexer implements ITypeRequestor, Su
this.cud = this.basicParser.parse(this.compilationUnit, new CompilationResult(this.compilationUnit, 0, 0, this.options.maxProblemsPerUnit));
JavaModelManager.getJavaModelManager().cacheZipFiles(this); // use model only for caching
// Use a non model name environment to avoid locks, monitors and such.
- INameEnvironment nameEnvironment = IndexBasedJavaSearchEnvironment.create(Collections.singletonList((IJavaProject)javaProject), JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, true/*add primary WCs*/));
+ INameEnvironment nameEnvironment = new JavaSearchNameEnvironment(javaProject, JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, true/*add primary WCs*/));
this.lookupEnvironment = new LookupEnvironment(this, this.options, problemReporter, nameEnvironment);
reduceParseTree(this.cud);
//{ObjectTeams: need Dependencies configured:
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java
deleted file mode 100644
index 65c2e14da..000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015, 2018 Google, Inc 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:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.search.matching;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
-import org.eclipse.jdt.internal.core.JavaProject;
-
-public class IndexBasedJavaSearchEnvironment {
-
- public static INameEnvironment create(List<IJavaProject> javaProjects, org.eclipse.jdt.core.ICompilationUnit[] copies) {
- Iterator<IJavaProject> next = javaProjects.iterator();
- JavaSearchNameEnvironment result = new JavaSearchNameEnvironment(next.next(), copies);
-
- while (next.hasNext()) {
- result.addProjectClassPath((JavaProject)next.next());
- }
- return result;
- }
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
index 7c21e9803..3fcb71f1b 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
@@ -17,7 +17,9 @@ import static java.util.stream.Collectors.joining;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -40,6 +42,7 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.IModule;
import org.eclipse.jdt.internal.compiler.env.IModuleAwareNameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
@@ -159,6 +162,10 @@ public void cleanup() {
}
protected /* visible for testing only */ void addProjectClassPath(JavaProject javaProject) {
+ addProjectClassPath(javaProject, false);
+}
+
+void addProjectClassPath(JavaProject javaProject, boolean onlyExported) {
long start = 0;
if (NameLookup.VERBOSE) {
Util.verbose(" EXTENDING JavaSearchNameEnvironment"); //$NON-NLS-1$
@@ -166,7 +173,7 @@ protected /* visible for testing only */ void addProjectClassPath(JavaProject ja
start = System.currentTimeMillis();
}
- LinkedHashSet<ClasspathLocation> locations = computeClasspathLocations(javaProject);
+ LinkedHashSet<ClasspathLocation> locations = computeClasspathLocations(javaProject, onlyExported);
if (locations != null) this.locationSet.addAll(locations);
if (NameLookup.VERBOSE) {
@@ -177,6 +184,10 @@ protected /* visible for testing only */ void addProjectClassPath(JavaProject ja
}
private LinkedHashSet<ClasspathLocation> computeClasspathLocations(JavaProject javaProject) {
+ return computeClasspathLocations(javaProject, false);
+}
+
+private LinkedHashSet<ClasspathLocation> computeClasspathLocations(JavaProject javaProject, boolean onlyExported) {
IPackageFragmentRoot[] roots = null;
try {
@@ -195,7 +206,11 @@ private LinkedHashSet<ClasspathLocation> computeClasspathLocations(JavaProject j
int length = roots.length;
JavaModelManager manager = JavaModelManager.getJavaModelManager();
for (int i = 0; i < length; i++) {
- ClasspathLocation cp = mapToClassPathLocation(manager, (PackageFragmentRoot) roots[i], imd);
+ PackageFragmentRoot root = (PackageFragmentRoot) roots[i];
+ if (onlyExported && !isSourceOrExported(root)) {
+ continue;
+ }
+ ClasspathLocation cp = mapToClassPathLocation(manager, root, imd);
if (cp != null) {
try {
indexPackageNames(cp, roots[i]);
@@ -561,6 +576,16 @@ public char[][] getAllAutomaticModules() {
return set.toArray(new char[set.size()][]);
}
+public static INameEnvironment createWithReferencedProjects(IJavaProject javaProject, List<IJavaProject> referencedProjects, org.eclipse.jdt.core.ICompilationUnit[] copies) {
+ JavaSearchNameEnvironment result = new JavaSearchNameEnvironment(javaProject, copies);
+
+ Iterator<IJavaProject> next = referencedProjects.iterator();
+ while (next.hasNext()) {
+ result.addProjectClassPath((JavaProject)next.next(), true);
+ }
+ return result;
+}
+
private static boolean isComplianceJava9OrHigher(IJavaProject javaProject) {
if (javaProject == null) {
return false;
@@ -607,4 +632,15 @@ private static boolean hasSystemModule(PackageFragmentRoot fragmentRoot) {
}
return false;
}
+
+private static boolean isSourceOrExported(PackageFragmentRoot root) {
+ boolean isExported = true; // if we run into exceptions, assume exported
+ try {
+ IClasspathEntry entry = root.getRawClasspathEntry();
+ isExported = entry.getEntryKind() == IClasspathEntry.CPE_SOURCE || entry.isExported();
+ } catch (JavaModelException e) {
+ Util.log(e, "Error checking whether package fragment root is exported!"); //$NON-NLS-1$
+ }
+ return isExported;
+}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index fad008d2a..64a7e90c4 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -1329,14 +1329,13 @@ public void initialize(JavaProject project, int possibleMatchSize) throws JavaMo
SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(this.workingCopies);
List<IJavaProject> projects = new ArrayList<>();
- projects.add(project);
if (this.pattern.focus != null) {
IJavaProject focusProject = this.pattern.focus.getJavaProject();
if (!project.equals(focusProject)) {
projects.add(focusProject);
}
}
- this.nameEnvironment = IndexBasedJavaSearchEnvironment.create(projects, this.workingCopies);
+ this.nameEnvironment = JavaSearchNameEnvironment.createWithReferencedProjects(project, projects, this.workingCopies);
// create lookup environment
Map map = project.getOptions(true);

Back to the top