Merge remote-tracking branch 'origin/master' into BETA_JAVA15
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/.cvsignore b/org.eclipse.jdt.compiler.apt.tests/lib/.cvsignore
deleted file mode 100644
index 476f129..0000000
--- a/org.eclipse.jdt.compiler.apt.tests/lib/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-apttestprocessors.jar
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
index 78d56c4..05cd7f6 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/java14api.jar b/org.eclipse.jdt.compiler.apt.tests/lib/java14api.jar
index fcf9985..e24da08 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/java14api.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/java14api.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java14ElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java14ElementProcessor.java
index b8042e3..435ed7f 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java14ElementProcessor.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java14ElementProcessor.java
@@ -19,6 +19,7 @@
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -43,10 +44,13 @@
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.RecordComponentElement;
import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.ElementScanner14;
import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor;
@@ -157,7 +161,7 @@
List<? extends RecordComponentElement> recordComponents = record.getRecordComponents();
// Test that in the first round, we don't get an NPE
assertNotNull("recordComponents Should not be null", recordComponents);
- assertEquals("recordComponents Should not be null", 1, recordComponents.size());
+ assertEquals("recordComponents Should not be null", 5, recordComponents.size());
}
/*
* Test for presence of record component in a record element
@@ -175,7 +179,7 @@
assertNotNull("enclosedElements for record should not be null", enclosedElements);
List<RecordComponentElement> recordComponentsIn = ElementFilter.recordComponentsIn(enclosedElements);
int size = recordComponentsIn.size();
- assertEquals("incorrect no of record components", 1, size);
+ assertEquals("incorrect no of record components", 5, size);
Element element = recordComponentsIn.get(0);
assertEquals("Incorrect kind of element", ElementKind.RECORD_COMPONENT, element.getKind());
RecordComponentElement recordComponent = (RecordComponentElement) element;
@@ -281,12 +285,48 @@
assertNotNull("enclosedElements for record should not be null", enclosedElements);
List<RecordComponentElement> recordComponentsIn = ElementFilter.recordComponentsIn(enclosedElements);
int size = recordComponentsIn.size();
- assertEquals("incorrect no of record components", 1, size);
+ assertEquals("incorrect no of record components", 5, size);
Element element = recordComponentsIn.get(0);
assertEquals("Incorrect kind of element", ElementKind.RECORD_COMPONENT, element.getKind());
RecordComponentElement recordComponent = (RecordComponentElement) element;
-
verifyAnnotations(recordComponent, new String[]{"@MyAnnot()"});
+
+ element = recordComponentsIn.get(1);
+ assertEquals("Incorrect kind of element", ElementKind.RECORD_COMPONENT, element.getKind());
+ recordComponent = (RecordComponentElement) element;
+ verifyAnnotations(recordComponent, new String[]{"@MyAnnot2()"});
+ }
+ public void testRecords4a() {
+ Set<? extends Element> elements = roundEnv.getRootElements();
+ TypeElement record = null;
+ for (Element element : elements) {
+ if ("Point".equals(element.getSimpleName().toString())) {
+ record = (TypeElement) element;
+ }
+ }
+ assertNotNull("TypeElement for record should not be null", record);
+ verifyAnnotations(record, new String[]{"@Deprecated()"});
+
+ List<? extends Element> enclosedElements = record.getEnclosedElements();
+ assertNotNull("enclosedElements for record should not be null", enclosedElements);
+ List<RecordComponentElement> recordComponentsIn = ElementFilter.recordComponentsIn(enclosedElements);
+ int size = recordComponentsIn.size();
+ assertEquals("incorrect no of record components", 5, size);
+
+ Element element = recordComponentsIn.get(2);
+ assertEquals("Incorrect kind of element", ElementKind.RECORD_COMPONENT, element.getKind());
+ RecordComponentElement recordComponent = (RecordComponentElement) element;
+ verifyAnnotations(recordComponent, new String[]{});
+
+ element = recordComponentsIn.get(3);
+ assertEquals("Incorrect kind of element", ElementKind.RECORD_COMPONENT, element.getKind());
+ recordComponent = (RecordComponentElement) element;
+ verifyAnnotations(recordComponent, new String[]{});
+
+ element = recordComponentsIn.get(4);
+ assertEquals("Incorrect kind of element", ElementKind.RECORD_COMPONENT, element.getKind());
+ recordComponent = (RecordComponentElement) element;
+ verifyAnnotations(recordComponent, new String[]{});
}
public void testRecords5() {
Map<String, TypeKind> expRecComps = new HashMap<>();
@@ -383,6 +423,68 @@
assertEquals("Accessor method name incorrect", record.getSimpleName().toString(), method.getSimpleName().toString());
}
}
+ public void testRecords8() {
+ boolean result = false;
+ Object r = "DEFAULT";
+ Object param = new Object();
+ ScannerImpl<Object, Object> es = new ScannerImpl<>(r);
+
+ Element e = _elementUtils.getTypeElement("records.Record2");
+ List<? extends Element> recordElements = e.getEnclosedElements();
+ for (Element recComp : recordElements) {
+ if (recComp.getKind() == ElementKind.RECORD_COMPONENT) {
+ result = true;
+ Object r2 = recComp.accept(es, param);
+ assertSame("returned message not same", r, r2);
+ assertTrue("not visited", es.visited);
+ assertSame("Visited element not the same", recComp, es.el);
+ assertSame("Visited param not the same", param, es.param);
+ }
+ }
+ assertTrue("Test returned negative", result);
+ }
+ public void testRecords9() {
+ String[] arr1 = new String[] { "x", "bigInt", "r1", "floatValue", "c", "recordInstance" };
+ TypeKind[] arr2 = new TypeKind[] { TypeKind.INT, TypeKind.DECLARED, TypeKind.DECLARED, TypeKind.FLOAT,
+ TypeKind.DECLARED, TypeKind.DECLARED };
+ List<String> names = Arrays.asList(arr1);
+ List<TypeKind> types = Arrays.asList(arr2);
+
+ Element record = _elementUtils.getTypeElement("records.R3");
+ List<? extends Element> allElements = record.getEnclosedElements();
+ List<RecordComponentElement> components = ElementFilter.recordComponentsIn(allElements);
+ List<ExecutableElement> accessors = components.stream().map
+ (RecordComponentElement::getAccessor).collect(Collectors.toList());
+ assertEquals("Size mismatch", names.size(), accessors.size());
+ for (ExecutableElement accessor : accessors) {
+ String name = accessor.getSimpleName().toString();
+ int indexOf = names.indexOf(name);
+ assertSame("Type kind not same for \"" + name + "\".", types.get(indexOf), accessor.getReturnType().getKind());
+ assertTrue("should be executable type for \"" + name + "\".", (accessor.asType() instanceof ExecutableType));
+ assertNull("should be null", accessor.getDefaultValue());
+ List<? extends AnnotationMirror> mirrors = accessor.getAnnotationMirrors();
+ if (name.equals("c") || name.equals("bigInt") || name.equals("r1")) {
+ assertEquals("annotations count mismatch for \"" + name + "\".", 1, mirrors.size());
+ Set<? extends ExecutableElement> accessorAnnotations = mirrors.get(0)
+ .getElementValues().keySet();
+ assertEquals("annotations type element mismatch for \"" + name + "\".", 1, accessorAnnotations.size());
+ int val = (int) accessorAnnotations.toArray(new ExecutableElement[0])[0].getDefaultValue()
+ .getValue();
+ assertEquals("Incorrect default value for \"" + name + "\".", 1, val);
+ }
+ if (name.equals("floatValue") || name.equals("x")) {
+ assertEquals("annotations count mismatch for \"" + name + "\".", 0, mirrors.size());
+ }
+ if (name.equals("recordInstance")) {
+ assertEquals("annotations count mismatch for \"" + name + "\".", 2, mirrors.size());
+ }
+ assertTrue("Parameters should be empty for \"" + name + "\".", accessor.getParameters().isEmpty());
+ assertTrue("Thrown types should be empty for \"" + name + "\".", accessor.getThrownTypes().isEmpty());
+ assertTrue("Type parameters should be empty for \"" + name + "\".", accessor.getTypeParameters().isEmpty());
+ assertFalse("Should not be default for \"" + name + "\".", accessor.isDefault());
+ assertFalse("Should not be varargs for \"" + name + "\".", accessor.isVarArgs());
+ }
+ }
@Override
public void reportError(String msg) {
@@ -524,4 +626,55 @@
super(msg);
}
}
+
+ class ScannerImpl<R, P> extends ElementScanner14<R, P> {
+ public Object el;
+ boolean isType;
+ boolean isMethod;
+ public boolean visited;
+ public boolean scanned;
+ R result;
+ public Object param;
+
+ public List<TypeParameterElement> params = new ArrayList<>();
+
+ public ScannerImpl() {
+ super();
+ }
+
+ public ScannerImpl(R r) {
+ super(r);
+ }
+
+ @Override
+ public R visitType(TypeElement e, P p) {
+ el = e;
+ param = p;
+ isType = true;
+ return super.visitType(e, p);
+ }
+
+ @Override
+ public R visitExecutable(ExecutableElement e, P p) {
+ isMethod = true;
+ el = e;
+ param = p;
+ return super.visitExecutable(e, p);
+ }
+
+ public R visitRecordComponent(RecordComponentElement e, P p) {
+ el = e;
+ param = p;
+ visited = true;
+ return super.visitRecordComponent(e, p);
+ }
+
+ public R scan(Element e, P p) {
+ scanned = true;
+ if (e instanceof TypeParameterElement) {
+ params.add((TypeParameterElement) e);
+ }
+ return DEFAULT_VALUE;
+ }
+ }
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/MyAnnot.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/MyAnnot.java
index e7b47bc..5aea36c 100644
--- a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/MyAnnot.java
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/MyAnnot.java
@@ -5,6 +5,22 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-@Target({ElementType.FIELD, ElementType.TYPE})
+@Target({ElementType.RECORD_COMPONENT, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
-@interface MyAnnot {}
\ No newline at end of file
+@interface MyAnnot {}
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface MyAnnot2 {}
+
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@interface MyAnnot3 {}
+
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@interface MyAnnot4 {}
+
+
+@Target({ElementType.TYPE_USE})
+@Retention(RetentionPolicy.RUNTIME)
+@interface MyAnnot5 {}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/Point.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/Point.java
index 1c7e324..9b8f88c 100644
--- a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/Point.java
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/Point.java
@@ -1,8 +1,12 @@
package records;
@Deprecated
-public record Point(@MyAnnot int comp_) {
- public Point {
- }
+public record Point(@MyAnnot int comp_,
+ @MyAnnot2 int comp2_,
+ @MyAnnot3 int comp3_,
+ @MyAnnot4 int comp4_,
+ @MyAnnot5 int comp5_) {
+
+ public Point {}
public boolean equals(Object o) {
return false;
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/R3.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/R3.java
new file mode 100644
index 0000000..946f960
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/R3.java
@@ -0,0 +1,34 @@
+package records;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.math.BigInteger;
+public record R3( @MyAnn4(value=5) int x,
+ @MyAnn2(value=5) BigInteger bigInt,
+ @MyAnn2(value=5) @MyAnn3(value=5) R1 r1,
+ @MyAnn3(value=5) float floatValue,
+ @MyAnn(value=5) Character c,
+ @MyAnn(value=5) @MyAnn2(value=5) @MyAnn3(value=5) R1 recordInstance){}
+
+record R1(){}
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.RECORD_COMPONENT, ElementType.METHOD})
+@interface MyAnn {
+ int value() default 1;
+}
+@Retention(RetentionPolicy.RUNTIME)
+@interface MyAnn2 {
+ int value() default 1;
+}
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.RECORD_COMPONENT})
+@interface MyAnn3 {
+ int value() default 1;
+}
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+@interface MyAnn4 {
+ int value() default 1;
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchDispatchTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchDispatchTests.java
index 48f87ab..24eec4f 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchDispatchTests.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchDispatchTests.java
@@ -149,6 +149,16 @@
internalTestWarnings(compiler, 1, "-nowarn", "-warn:+unused");
}
+ public void testNoWarningsInFolderWithEclipseCompiler() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTestWarnings(compiler, 0, "-warn:+unused", "-nowarn:[" + BatchTestUtils.getGenFolderName() + ']');
+ }
+
+ public void testNoWarningsInFolderWithEclipseCompiler2() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTestWarnings(compiler, 0, "-nowarn:[" + BatchTestUtils.getGenFolderName() + ']', "-warn:+unused");
+ }
+
private void internalTestWarnings(JavaCompiler compiler, int numberOfWarnings, String... extraOptions) throws IOException {
File targetFolder = TestUtils.concatPath(BatchTestUtils.getSrcFolderName(), "targets", "dispatch");
File inputFile = BatchTestUtils.copyResource("targets/dispatch/WarnGenClass.java", targetFolder);
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java14ElementsTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java14ElementsTests.java
index 4a411b1..518544f 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java14ElementsTests.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java14ElementsTests.java
@@ -46,7 +46,7 @@
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords2", null, "records", true);
}
- public void _testRecords2Javac() throws Exception {
+ public void testRecords2Javac() throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords2", null, "records", true);
}
@@ -70,10 +70,18 @@
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords4", null, "records", true);
}
- public void _testRecords4Javac() throws Exception {
+ public void testRecords4Javac() throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords4", null, "records", true);
}
+ public void _testRecords4a() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords4a", null, "records", true);
+ }
+ public void testRecords4aJavac() throws Exception {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords4a", null, "records", true);
+ }
public void testRecords5() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords5", null, "records", true);
@@ -98,6 +106,22 @@
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords7", null, "records", true);
}
+ public void testRecords8() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords8", null, "records", true);
+ }
+ public void testRecords8Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords8", null, "records", true);
+ }
+ public void testRecords9() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords9", null, "records", true);
+ }
+ public void testRecords9Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "14", "testRecords9", null, "records", true);
+ }
protected void internalTestWithPreview(JavaCompiler compiler, String processor, String compliance,
String testMethod, String testClass, String resourceArea, boolean preview) throws IOException {
diff --git a/org.eclipse.jdt.compiler.apt/lib/java14api.jar b/org.eclipse.jdt.compiler.apt/lib/java14api.jar
index fcf9985..e24da08 100644
--- a/org.eclipse.jdt.compiler.apt/lib/java14api.jar
+++ b/org.eclipse.jdt.compiler.apt/lib/java14api.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
index d061ab6..b731cc0 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
@@ -42,7 +42,7 @@
public class BatchFilerImpl implements Filer {
protected final BaseAnnotationProcessorManager _dispatchManager;
- protected final BaseProcessingEnvImpl _env;
+ protected final BatchProcessingEnvImpl _env;
protected final JavaFileManager _fileManager;
protected final HashSet<URI> _createdFiles;
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java
index d13d2cb..cbf8abe 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java
@@ -143,4 +143,7 @@
return _compilerOwner.compilerLocale;
}
+ public boolean shouldIgnoreOptionalProblems(char[] fileName) {
+ return Main.shouldIgnoreOptionalProblems(this._compilerOwner.ignoreOptionalProblemsFromFolders, fileName);
+ }
}
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java
index b6b97e8..a5fbbcd 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java
@@ -225,7 +225,7 @@
//TODO: support encoding
switch(this.getKind()) {
case SOURCE :
- CompilationUnit unit = new CompilationUnit(null, _fileName, null /* encoding */);
+ CompilationUnit unit = new CompilationUnit(null, _fileName, null /* encoding */, null, this._filer._env.shouldIgnoreOptionalProblems(_fileName.toCharArray()), null);
_filer.addNewUnit(unit);
break;
case CLASS :
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/RecordComponentElementImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/RecordComponentElementImpl.java
index 2ce4c12..9be30c6 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/RecordComponentElementImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/RecordComponentElementImpl.java
@@ -15,6 +15,7 @@
package org.eclipse.jdt.internal.compiler.apt.model;
import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ElementVisitor;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.RecordComponentElement;
@@ -45,4 +46,8 @@
}
return null;
}
+ @Override
+ public <R, P> R accept(ElementVisitor<R, P> visitor, P param) {
+ return visitor.visitRecordComponent(this, param);
+ }
}
diff --git a/org.eclipse.jdt.compiler.tool.tests/lib/java14api.jar b/org.eclipse.jdt.compiler.tool.tests/lib/java14api.jar
index fcf9985..e24da08 100644
--- a/org.eclipse.jdt.compiler.tool.tests/lib/java14api.jar
+++ b/org.eclipse.jdt.compiler.tool.tests/lib/java14api.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.tool/lib/java14api.jar b/org.eclipse.jdt.compiler.tool/lib/java14api.jar
index fcf9985..e24da08 100644
--- a/org.eclipse.jdt.compiler.tool/lib/java14api.jar
+++ b/org.eclipse.jdt.compiler.tool/lib/java14api.jar
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Bug562420Test.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Bug562420Test.java
new file mode 100644
index 0000000..90f691a
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Bug562420Test.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Stephan Herrmann 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:
+ * Stephan Herrmann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.builder;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+import junit.framework.Test;
+
+public class Bug562420Test extends BuilderTests {
+ public Bug562420Test(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return buildTestSuite(Bug562420Test.class);
+ }
+ public void testBuilderRegression() throws JavaModelException, Exception {
+ IPath projectPath = env.addProject("Bug562420Test", "9");
+ env.removePackageFragmentRoot(projectPath, "");
+ IPath src = env.addPackageFragmentRoot(projectPath, "src");
+
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ IPath testAppPath = env.addClass(src, "org.easylibs.test", "TestApp",
+ "package org.easylibs.test;\n" +
+ "public class TestApp {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"Hello World\");\n" +
+ " }\n" +
+ "}\n");
+ env.addFile(testAppPath.removeLastSegments(1), "package-info.java",
+ "package org.easylibs.test;");
+ env.addFile(src, "module-info.java",
+ "module test {\n" +
+ " requires java.base;\n" +
+ " exports org.easylibs.test;\n" +
+ "}\n");
+ fullBuild();
+ if (CompilerOptions.versionToJdkLevel(System.getProperty("java.specification.version")) < ClassFileConstants.JDK9) {
+ expectingProblemsFor(projectPath,
+ "Problem : java.base cannot be resolved to a module [ resource : </Bug562420Test/src/module-info.java> range : <24,33> category : <160> severity : <2>]");
+ } else {
+ expectingNoProblems();
+ }
+
+ env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_SOURCE, "1.8");
+ env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, "1.8");
+ fullBuild();
+ expectingProblemsFor(projectPath,
+ "Problem : Syntax error on token \".\", , expected [ resource : </Bug562420Test/src/module-info.java> range : <28,29> category : <20> severity : <2>]\n" +
+ "Problem : Syntax error on token \".\", = expected [ resource : </Bug562420Test/src/module-info.java> range : <47,48> category : <20> severity : <2>]\n" +
+ "Problem : Syntax error on token \"module\", interface expected [ resource : </Bug562420Test/src/module-info.java> range : <0,6> category : <20> severity : <2>]");
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BuilderTests.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BuilderTests.java
index 9cc8a59..fbb210a 100644
--- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BuilderTests.java
+++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BuilderTests.java
@@ -549,6 +549,7 @@
Bug531382Test.class,
Bug549457Test.class,
Bug561287Test.class,
+ Bug562420Test.class,
LeakTestsBefore9.class,
};
List<Class<?>> list = new ArrayList<>(Arrays.asList(classes));
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java
index 3eff433..88aa24d 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java
@@ -1938,7 +1938,7 @@
);
}
//TODO: Enable after Bug 552769 is fixed
-public void _test0042() {
+public void test0042() {
String[] testFiles = new String[] {
"X.java",
"void ___eval() {\n" +
@@ -2035,28 +2035,23 @@
"Syntax error, insert \"EnumBody\" to complete CompilationUnit\n" +
"----------\n";
- String expected_Java14_ProblemLog =
+ String expectedJ14ProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 1)\n" +
" void ___eval() {\n" +
" ^^^^\n" +
"Syntax error on token \"void\", record expected\n" +
"----------\n" +
- "2. ERROR in X.java (at line 1)\n" +
- " void ___eval() {\n" +
- " ^\n" +
- "Syntax error on token \")\", { expected after this token\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 23)\n" +
- " }\n" +
- " ^\n" +
- "Syntax error, insert \"}\" to complete RecordBody\n" +
+ "2. ERROR in X.java (at line 2)\n" +
+ " new Runnable() {\n" +
+ " ^^^\n" +
+ "Syntax error on token \"new\", record expected\n" +
"----------\n";
runComplianceParserTest(
testFiles,
- expected_Java14_ProblemLog,
- expected_Java14_ProblemLog,
- expected_Java14_ProblemLog
+ expected13ProblemLog,
+ expected14ProblemLog,
+ (this.complianceLevel < ClassFileConstants.JDK14 ? expected15ProblemLog : expectedJ14ProblemLog)
);
}
/*
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index d197a29..064aa6e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -1249,6 +1249,7 @@
expectedProblemAttributes.put("RecordComponentCannotBeVoid", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("RecordIllegalVararg", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("RecordStaticReferenceToOuterLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
+ expectedProblemAttributes.put("RecordCannotDefineRecordInLocalType", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
StringBuffer failures = new StringBuffer();
StringBuffer correctResult = new StringBuffer(70000);
Field[] fields = (iProblemClass = IProblem.class).getFields();
@@ -2270,6 +2271,7 @@
expectedProblemAttributes.put("RecordComponentCannotBeVoid", SKIP);
expectedProblemAttributes.put("RecordIllegalVararg", SKIP);
expectedProblemAttributes.put("RecordStaticReferenceToOuterLocalVariable",SKIP);
+ expectedProblemAttributes.put("RecordCannotDefineRecordInLocalType",SKIP);
Map constantNamesIndex = new HashMap();
Field[] fields = JavaCore.class.getFields();
for (int i = 0, length = fields.length; i < length; i++) {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_4.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_4.java
index 654645f..3a230b5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_4.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_4.java
@@ -2594,7 +2594,7 @@
/*
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=47227
*/
-public void _test079() {
+public void test079() {
this.runNegativeTest(
new String[] {
"Hello.java",
@@ -2625,18 +2625,21 @@
"----------\n" +
"1. ERROR in Hello.java (at line 1)\n" +
" void ___eval() {\n" +
- " ^^^^\n" +
- "Syntax error on token \"void\", record expected\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "Syntax error on tokens, delete these tokens\n" +
"----------\n" +
- "2. ERROR in Hello.java (at line 1)\n" +
- " void ___eval() {\n" +
- " ^\n" +
- "Syntax error on token \")\", { expected after this token\n" +
- "----------\n" +
- "3. ERROR in Hello.java (at line 23)\n" +
- " }\n" +
- " ^\n" +
- "Syntax error, insert \"}\" to complete RecordBody\n" +
+ "2. ERROR in Hello.java (at line 2)\n" +
+ " new Runnable() {\n" +
+ " int ___run() throws Throwable {\n" +
+ " return blah;\n" +
+ " }\n" +
+ " private String blarg;\n" +
+ " public void run() {\n" +
+ " }\n" +
+ " };\n" +
+ "}\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Syntax error on tokens, delete these tokens\n" +
"----------\n"
);
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_5.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_5.java
index 1626778..6192c7a 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_5.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Compliance_1_5.java
@@ -2722,7 +2722,62 @@
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=47227
*/
// TODO: Enable after Bug 552769 is fixed
-public void _test079() {
+public void test079() {
+
+ String expectedErrorLog = "----------\n" +
+ "1. ERROR in Hello.java (at line 1)\n" +
+ " void ___eval() {\n" +
+ " ^^^^\n" +
+ "Syntax error on token \"void\", @ expected\n" +
+ "----------\n" +
+ "2. ERROR in Hello.java (at line 1)\n" +
+ " void ___eval() {\n" +
+ " ^\n" +
+ "Syntax error on token \")\", delete this token\n" +
+ "----------\n" +
+ "3. ERROR in Hello.java (at line 9)\n" +
+ " };\n" +
+ "}\n" +
+ " ^^^^\n" +
+ "Syntax error on tokens, delete these tokens\n" +
+ "----------\n" +
+ "4. ERROR in Hello.java (at line 23)\n" +
+ " }\n" +
+ " ^\n" +
+ "Syntax error, insert \"}\" to complete ClassBody\n" +
+ "----------\n" +
+ "5. ERROR in Hello.java (at line 23)\n" +
+ " }\n" +
+ " ^\n" +
+ "Syntax error, insert \"}\" to complete MemberValue\n" +
+ "----------\n" +
+ "6. ERROR in Hello.java (at line 23)\n" +
+ " }\n" +
+ " ^\n" +
+ "Syntax error, insert \")\" to complete Modifiers\n" +
+ "----------\n" +
+ "7. ERROR in Hello.java (at line 23)\n" +
+ " }\n" +
+ " ^\n" +
+ "Syntax error, insert \"enum Identifier\" to complete EnumHeader\n" +
+ "----------\n" +
+ "8. ERROR in Hello.java (at line 23)\n" +
+ " }\n" +
+ " ^\n" +
+ "Syntax error, insert \"EnumBody\" to complete CompilationUnit\n" +
+ "----------\n";
+ String expectedErrorLog_J14 = "----------\n" +
+ "1. ERROR in Hello.java (at line 1)\n" +
+ " void ___eval() {\n" +
+ " ^^^^\n" +
+ "Syntax error on token \"void\", record expected\n" +
+ "----------\n" +
+ "2. ERROR in Hello.java (at line 2)\n" +
+ " new Runnable() {\n" +
+ " ^^^\n" +
+ "Syntax error on token \"new\", record expected\n" +
+ "----------\n";
+
this.runNegativeTest(
new String[] {
"Hello.java",
@@ -2750,22 +2805,8 @@
" }\n" +
"}\n"
},
- "----------\n" +
- "1. ERROR in Hello.java (at line 1)\n" +
- " void ___eval() {\n" +
- " ^^^^\n" +
- "Syntax error on token \"void\", record expected\n" +
- "----------\n" +
- "2. ERROR in Hello.java (at line 1)\n" +
- " void ___eval() {\n" +
- " ^\n" +
- "Syntax error on token \")\", { expected after this token\n" +
- "----------\n" +
- "3. ERROR in Hello.java (at line 23)\n" +
- " }\n" +
- " ^\n" +
- "Syntax error, insert \"}\" to complete RecordBody\n" +
- "----------\n"
+ this.complianceLevel < ClassFileConstants.JDK14 ?
+ expectedErrorLog :expectedErrorLog_J14
);
}
/*
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
index 94add4c..9e73da1 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
@@ -5400,6 +5400,47 @@
true,
customOptions);
}
+ public void _test0178a() {
+ if (this.complianceLevel < ClassFileConstants.JDK14)
+ return;
+ Map customOptions = getCompilerOptions();
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X <T> {\n" +
+ " \n" +
+ " T foo(T t) {\n" +
+ " boolean b = false;\n" +
+ " if (t instanceof X<T>) {\n" +
+ " return t;\n" +
+ " } else if (t instanceof X<String>) {\n" +
+ " return t;\n" +
+ " } else if (t instanceof X<?>) {\n" + // ok
+ " return t;\n" +
+ " } else if (t instanceof T) {\n" +
+ " return t;\n" +
+ " } else if (t instanceof X) {\n" +
+ " return t;\n" +
+ " }\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " if (t instanceof X<T>) {\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "Type mismatch: cannot convert from T to X<T>\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 7)\n" +
+ " } else if (t instanceof X<String>) {\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "Type mismatch: cannot convert from T to X<String>\n" +
+ "----------\n",
+ null,
+ true,
+ customOptions);
+ }
// 61507
public void test0179() {
this.runConformTest(
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest.java
index d566b97..20dffa7 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -47,6 +47,7 @@
ALL_CLASSES.add(JavadocTestMixed.class);
ALL_CLASSES.add(JavadocTestForClass.class);
ALL_CLASSES.add(JavadocTestForRecord.class);
+ ALL_CLASSES.add(JavadocTestForModule.class);
ALL_CLASSES.add(JavadocTestForConstructor.class);
ALL_CLASSES.add(JavadocTestForField.class);
ALL_CLASSES.add(JavadocTestForInterface.class);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTestForModule.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTestForModule.java
index 00ecdbc..466ac72 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTestForModule.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTestForModule.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2019 IBM Corporation and others.
+ * Copyright (c) 2019, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -479,27 +479,17 @@
buffer.toString(),
"",
"----------\n" +
- "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 2)\n" +
- " @provides p.I\n" +
- " ^^^\n" +
- "Javadoc: Invalid provides class\n" +
- "----------\n" +
- "2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 3)\n" +
- " @uses java.util.Currenc\n" +
- " ^^^^^^^^^^^^^^^^^\n" +
- "Javadoc: Invalid uses class\n" +
- "----------\n" +
- "3. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 7)\n" +
+ "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 7)\n" +
" provides p.I1 with p.P1;\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Javadoc: Missing provides tag\n" +
"----------\n" +
- "4. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 8)\n" +
+ "2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 8)\n" +
" uses java.util.Currency;\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Javadoc: Missing uses tag\n" +
"----------\n" +
- "4 problems (4 errors)\n",
+ "2 problems (2 errors)\n",
false,
"missing and invalid tags");
}
@@ -895,27 +885,17 @@
buffer.toString(),
"",
"----------\n" +
- "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 2)\n" +
- " * @provides p.I\n" +
- " ^^^\n" +
- "Javadoc: Invalid provides class\n" +
- "----------\n" +
- "2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 3)\n" +
- " * @uses java.util.Currenc\n" +
- " ^^^^^^^^^^^^^^^^^\n" +
- "Javadoc: Invalid uses class\n" +
- "----------\n" +
- "3. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 7)\n" +
+ "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 7)\n" +
" provides p.I1 with p.P1;\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Javadoc: Missing provides tag\n" +
"----------\n" +
- "4. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 8)\n" +
+ "2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 8)\n" +
" uses java.util.Currency;\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Javadoc: Missing uses tag\n" +
"----------\n" +
- "4 problems (4 errors)\n",
+ "2 problems (2 errors)\n",
false,
"invalid tags");
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index 98943bd..4683011 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -18142,4 +18142,108 @@
"----------\n";
runner.runWarningTest();
}
+public void testBug562347_561280c9() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "Example.java",
+ "import java.util.HashMap;\n" +
+ "import java.util.Map;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "\n" +
+ "@NonNullByDefault\n" +
+ "public class Example {\n" +
+ " static <X> X f(X x) {\n" +
+ " return x;\n" +
+ " }\n" +
+ "\n" +
+ " public void g() {\n" +
+ " Object x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;\n" +
+ " Object x10, x11, x12, x13, x14, x15, x16, x17, x18, x19;\n" +
+ " Object x20, x21, x22, x23, x24, x25, x26, x27, x28, x29;\n" +
+ " Object x30, x31, x32, x33, x34, x35, x36, x37, x38, x39;\n" +
+ " Object x40, x41, x42, x43, x44, x45, x46, x47, x48, x49;\n" +
+ " Object x50, x51, x52, x53, x54, x55, x56, x57, x58, x59;\n" +
+ " Object x60;\n" +
+ " Object x61;\n" +
+ " for (Map.Entry<String, String> entry : new HashMap<String, String>().entrySet()) {\n" +
+ " if (f(entry.getKey()) != null) {\n" +
+ " continue;\n" +
+ " }\n" +
+ " String x = \"asdf\";\n" +
+ " x.hashCode();\n" +
+ " }\n" +
+ " }\n" +
+ "}\n" +
+ "\n"
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in Example.java (at line 22)\n" +
+ " if (f(entry.getKey()) != null) {\n" +
+ " ^^^^^^^^^^^^^^^^^\n" +
+ "Redundant null check: comparing \'@NonNull String\' against null\n" +
+ "----------\n" +
+ "2. WARNING in Example.java (at line 25)\n" +
+ " String x = \"asdf\";\n" +
+ " ^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n");
+}
+public void testBug562347() {
+ Runner runner = new Runner();
+ runner.testFiles =
+ new String[] {
+ "NotificationListingHolder.java",
+ "@SuppressWarnings(\"unused\")\n" +
+ "public final class NotificationListingHolder {\n" +
+ " private String f1,f2,f3,f4;\n" +
+ "\n" +
+ " private void setupActionButtons() {\n" +
+ " Test listItemNotificationsBinding2;\n" +
+ " boolean z;\n" +
+ " String a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53,a54,a55,a56,a57,a58;\n" +
+ " if (z) {\n" +
+ " String button4 = listItemNotificationsBinding2.field;\n" +
+ " if (listItemNotificationsBinding2 != null) {\n" +
+ " return;\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "class Test {\n" +
+ " public final String field;\n" +
+ "}"
+ };
+ runner.expectedCompilerLog =
+ "----------\n" +
+ "1. ERROR in NotificationListingHolder.java (at line 9)\n" +
+ " if (z) {\n" +
+ " ^\n" +
+ "The local variable z may not have been initialized\n" +
+ "----------\n" +
+ "2. ERROR in NotificationListingHolder.java (at line 10)\n" +
+ " String button4 = listItemNotificationsBinding2.field;\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "The local variable listItemNotificationsBinding2 may not have been initialized\n" +
+ "----------\n" +
+ "3. ERROR in NotificationListingHolder.java (at line 11)\n" +
+ " if (listItemNotificationsBinding2 != null) {\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "The local variable listItemNotificationsBinding2 may not have been initialized\n" +
+ "----------\n" +
+ "4. ERROR in NotificationListingHolder.java (at line 11)\n" +
+ " if (listItemNotificationsBinding2 != null) {\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Redundant null check: The variable listItemNotificationsBinding2 cannot be null at this location\n" +
+ "----------\n" +
+ "5. ERROR in NotificationListingHolder.java (at line 19)\n" +
+ " public final String field;\n" +
+ " ^^^^^\n" +
+ "The blank final field field may not have been initialized\n" +
+ "----------\n";
+ runner.classLibraries = this.LIBS;
+ runner.runNegativeTest();
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching15Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching15Test.java
index 3972400..2f0676c 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching15Test.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching15Test.java
@@ -1674,7 +1674,7 @@
" foo(new String[] {\"abcd\"});\n" +
" }\n" +
" public static void foo(Object[] obj) {\n" +
- " for(int i = 0; (obj[i] instanceof String s) && s.length() > 0 ; i++) {\n" +
+ " for(int i = 0; (obj[i] instanceof String s) && s.length() > 0 ;) {\n" +
" throw new IllegalArgumentException();\n" +
" }\n" +
" System.out.println(s);\n" +
@@ -1685,7 +1685,7 @@
"1. ERROR in X38.java (at line 10)\n" +
" System.out.println(s);\n" +
" ^\n" +
- "s cannot be resolved to a variable\n" +
+ "The pattern variable s is not in scope in this location\n" +
"----------\n",
"",
null,
@@ -2011,4 +2011,138 @@
compilerOptions);
compilerOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, old);
}
-}
\ No newline at end of file
+ public void test052() {
+ Map<String, String> compilerOptions = getCompilerOptions(true);
+ String old = compilerOptions.get(CompilerOptions.OPTION_PreserveUnusedLocal);
+ compilerOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT);
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " @SuppressWarnings(\"preview\")\n" +
+ " public static void main(String args[]) {\n" +
+ " String result = null;\n" +
+ " Object obj = \"abc\";\n" +
+ " int i = switch (0) {\n" +
+ " case 1 -> {\n" +
+ " yield 1;\n" +
+ " }\n" +
+ " default -> {\n" +
+ " for (int j = 0; !(obj instanceof String s);) {\n" +
+ " obj = null;\n" +
+ " }\n" +
+ " result = s;\n" +
+ " System.out.println(result);\n" +
+ " yield 2;\n" +
+ " }\n" +
+ " };\n" +
+ " System.out.println(i);\n" +
+ " }\n" +
+ "}\n",
+ },
+ "abc\n" +
+ "2",
+ compilerOptions);
+ compilerOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, old);
+ }
+ public void _testBug562392a() {
+ Map<String, String> compilerOptions = getCompilerOptions(true);
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X<T> {\n" +
+ " public boolean foo(T obj) {\n" +
+ " if (obj instanceof T s) {\n" +
+ " System.out.println(s);\n" +
+ " }\n" +
+ " return true;\n" +
+ " }\n" +
+ " public static void main(String argv[]) {\n" +
+ " String s = \"x\";\n" +
+ " System.out.println(new X<String>().foo(s));\n" +
+ " }\n" +
+ "}\n",
+ },
+ "x\n" +
+ "true",
+ compilerOptions);
+ }
+ public void _testBug562392b() {
+ Map<String, String> compilerOptions = getCompilerOptions(true);
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X<T> {\n" +
+ " public boolean foo(Object obj) {\n" +
+ " if (obj instanceof T) {\n" +
+ " return false;\n" +
+ " }\n" +
+ " return true;\n" +
+ " }\n" +
+ " public static void main(String argv[]) {\n" +
+ " System.out.println(\"\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " if (obj instanceof T) {\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "Type mismatch: cannot convert from Object to T\n" +
+ "----------\n",
+ "",
+ null,
+ true,
+ compilerOptions);
+ }
+ public void _testBug562392c() {
+ Map<String, String> compilerOptions = getCompilerOptions(true);
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "@SuppressWarnings(\"preview\")\n" +
+ "public class X<T> {\n" +
+ " public boolean foo(Object obj) {\n" +
+ " if (obj instanceof T t) {\n" +
+ " return false;\n" +
+ " }\n" +
+ " return true;\n" +
+ " }\n" +
+ " public static void main(String argv[]) {\n" +
+ " System.out.println(\"\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " if (obj instanceof T t) {\n" +
+ " ^^^^^^^^^^^^^^^^^^\n" +
+ "Type mismatch: cannot convert from Object to T\n" +
+ "----------\n",
+ "",
+ null,
+ true,
+ compilerOptions);
+ }
+ public void _testBug562392d() {
+ Map<String, String> compilerOptions = getCompilerOptions(true);
+ runConformTest(
+ new String[] {
+ "X.java",
+ "@SuppressWarnings(\"preview\")\n" +
+ "public class X<T> {\n" +
+ " public boolean foo(Object obj) {\n" +
+ " if (null instanceof T t) {\n" +
+ " return false;\n" +
+ " }\n" +
+ " return true;\n" +
+ " }\n" +
+ " public static void main(String argv[]) {\n" +
+ " System.out.println(\"\");\n" +
+ " }\n" +
+ "}\n",
+ },
+ "",
+ compilerOptions);
+ }
+}
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 2d148f7..8a272a0 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
@@ -50,6 +50,7 @@
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+ defaultOptions.put(CompilerOptions.OPTION_Store_Annotations, CompilerOptions.ENABLED);
return defaultOptions;
}
@@ -2507,4 +2508,230 @@
true
);
}
+public void testBug561778_001() throws IOException, ClassFormatException {
+ runConformTest(
+ new String[] {
+ "XTest.java",
+ "public class XTest{\n" +
+ " static <T> T test(X<T> box) {\n" +
+ " return box.value(); /* */\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(0);\n" +
+ " }\n" +
+ "}\n",
+ "X.java",
+ "public record X<T>(T value) {\n" +
+ "}"
+ },
+ "0");
+ String expectedOutput =
+ " // Method descriptor #24 ()Ljava/lang/Object;\n" +
+ " // Signature: ()TT;\n" +
+ " // Stack: 1, Locals: 1\n" +
+ " public java.lang.Object value();\n";
+ RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "X.class", ClassFileBytesDisassembler.SYSTEM);
+}
+public void testBug561778_002() throws IOException, ClassFormatException {
+ runConformTest(
+ new String[] {
+ "XTest.java",
+ "public class XTest{\n" +
+ " static <T> Y<T> test(X<T> box) {\n" +
+ " return box.value(); /* */\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(0);\n" +
+ " }\n" +
+ "}\n",
+ "X.java",
+ "public record X<T>(Y<T> value) {\n" +
+ "}\n" +
+ "class Y<T> {\n" +
+ "}"
+ },
+ "0");
+ String expectedOutput =
+ " // Method descriptor #24 ()LY;\n" +
+ " // Signature: ()LY<TT;>;\n" +
+ " // Stack: 1, Locals: 1\n" +
+ " public Y value();\n";
+ RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "X.class", ClassFileBytesDisassembler.SYSTEM);
+}
+public void testBug562219_001() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n"+
+ " public void foo() {\n"+
+ " @SuppressWarnings(\"unused\")\n"+
+ " class Y {\n"+
+ " @SuppressWarnings(\"preview\")\n"+
+ " class Z {\n"+
+ " record R() {\n"+
+ " \n"+
+ " }\n"+
+ " }\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " record R() {\n" +
+ " ^\n" +
+ "A record declaration R is not allowed in a local inner class\n" +
+ "----------\n",
+ null,
+ true
+ );
+}
+public void testBug562219_002() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n"+
+ " public void foo() {\n"+
+ " @SuppressWarnings(\"unused\")\n"+
+ " class Y {\n"+
+ " @SuppressWarnings(\"preview\")\n"+
+ " record R() {}\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " record R() {}\n" +
+ " ^\n" +
+ "A record declaration R is not allowed in a local inner class\n" +
+ "----------\n",
+ null,
+ true
+ );
+}
+/*
+ * Test that annotation with implicit target as METHOD are included in the
+ * generated bytecode on the record component and its accessor method
+ */
+public void _test562250a() throws IOException, ClassFormatException {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.*;\n" +
+ "import java.lang.reflect.*;\n" +
+ "\n" +
+ "record Point(@Annot int a) {\n" +
+ "}\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface Annot {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) throws Exception {\n" +
+ " Class<?> cls = Class.forName(\"Point\");\n" +
+ " RecordComponent[] recordComponents = cls.getRecordComponents();\n" +
+ " for (RecordComponent recordComponent : recordComponents) {\n" +
+ " Annotation[] annotations = recordComponent.getAnnotations();\n" +
+ " System.out.println(\"RecordComponents:\");\n" +
+ " for (Annotation annot : annotations) {\n" +
+ " System.out.println(annot);\n" +
+ " }\n" +
+ " Method accessor = recordComponent.getAccessor();\n" +
+ " System.out.println(\"Accessors:\");\n" +
+ " annotations =accessor.getAnnotations();\n" +
+ " for (Annotation annot : annotations) {\n" +
+ " System.out.println(annot);\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}"
+ },
+ "RecordComponents:\n" +
+ "@Annot()\n" +
+ "Accessors:\n" +
+ "@Annot()");
+}
+/*
+ * Test that annotation with explicit target as METHOD are included in the
+ * generated bytecode on the record component and its accessor method
+ */
+public void _test562250b() throws IOException, ClassFormatException {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.*;\n" +
+ "import java.lang.reflect.*;\n" +
+ "\n" +
+ "record Point(@Annot int a) {\n" +
+ "}\n" +
+ "@Target({ElementType.METHOD})\n"+
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface Annot {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) throws Exception {\n" +
+ " Class<?> cls = Class.forName(\"Point\");\n" +
+ " RecordComponent[] recordComponents = cls.getRecordComponents();\n" +
+ " for (RecordComponent recordComponent : recordComponents) {\n" +
+ " Annotation[] annotations = recordComponent.getAnnotations();\n" +
+ " System.out.println(\"RecordComponents:\");\n" +
+ " for (Annotation annot : annotations) {\n" +
+ " System.out.println(annot);\n" +
+ " }\n" +
+ " Method accessor = recordComponent.getAccessor();\n" +
+ " System.out.println(\"Accessors:\");\n" +
+ " annotations =accessor.getAnnotations();\n" +
+ " for (Annotation annot : annotations) {\n" +
+ " System.out.println(annot);\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}"
+ },
+ "RecordComponents:\n" +
+ "@Annot()\n" +
+ "Accessors:\n" +
+ "@Annot()");
+}
+/*
+ * Test that even though annotations with FIELD as a target are permitted by the
+ * compiler on a record component, the generated bytecode doesn't contain these annotations
+ * on the record component.
+ */
+public void _test562250c() throws IOException, ClassFormatException {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.*;\n" +
+ "import java.lang.reflect.*;\n" +
+ "\n" +
+ "record Point(@Annot int a) {\n" +
+ "}\n" +
+ "@Target({ElementType.FIELD})\n"+
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface Annot {\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) throws Exception {\n" +
+ " Class<?> cls = Class.forName(\"Point\");\n" +
+ " RecordComponent[] recordComponents = cls.getRecordComponents();\n" +
+ " for (RecordComponent recordComponent : recordComponents) {\n" +
+ " Annotation[] annotations = recordComponent.getAnnotations();\n" +
+ " System.out.println(\"RecordComponents:\");\n" +
+ " for (Annotation annot : annotations) {\n" +
+ " System.out.println(annot);\n" +
+ " }\n" +
+ " Method accessor = recordComponent.getAccessor();\n" +
+ " System.out.println(\"Accessors:\");\n" +
+ " annotations =accessor.getAnnotations();\n" +
+ " for (Annotation annot : annotations) {\n" +
+ " System.out.println(annot);\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}"
+ },
+ "RecordComponents:\n" +
+ "Accessors:");
+}
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java
index 35979da..6c8ae9e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java
@@ -4611,4 +4611,63 @@
"----------\n");
}
+
+ public void testBug562129() {
+ if (this.complianceLevel < ClassFileConstants.JDK14) return;
+ runNegativeTest(
+ new String[] {
+ "SwitchExpressionError.java",
+ "class SwitchExpressionError {\n" +
+ "\n" +
+ " static boolean howMany(int k) {\n" +
+ " return false || switch (k) {\n" +
+ " case 1 -> true;\n" +
+ " case 2 -> Boolean.FALSE;\n" +
+ " case 3 -> r;\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in SwitchExpressionError.java (at line 4)\n" +
+ " return false || switch (k) {\n" +
+ " ^\n" +
+ "A switch expression should have a default case\n" +
+ "----------\n" +
+ "2. ERROR in SwitchExpressionError.java (at line 7)\n" +
+ " case 3 -> r;\n" +
+ " ^\n" +
+ "r cannot be resolved to a variable\n" +
+ "----------\n");
+ }
+ public void testBug562198_001() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n"+
+ " int a[] = {1, 2, 3};\n"+
+ " public int foo() {\n"+
+ " return switch (0) {\n"+
+ " case 0 -> {\n"+
+ " yield a[0];\n"+
+ " }\n"+
+ " default -> {\n"+
+ " try {\n"+
+ " // do nothing\n"+
+ " } finally {\n"+
+ " // do nothing\n"+
+ " }\n"+
+ " yield 0;\n"+
+ " }\n"+
+ " };\n"+
+ " }\n"+
+ " public static void main(String[] args) {\n"+
+ " System.out.println(new X().foo());\n"+
+ " }\n"+
+ "}\n"
+ },
+ "1");
+ }
+
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TextBlockTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TextBlockTest.java
index e8006e6..79f4631 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TextBlockTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TextBlockTest.java
@@ -1337,4 +1337,20 @@
true,
copy);
}
+ public void testBug562460() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static String textb = \"\"\"\n" +
+ "a\\sb\\sc\"\"\";\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(textb.equals(\"a b c\"));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "true",
+ getCompilerOptions(),
+ new String[] {"--enable-preview"});
+ }
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelCompletionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelCompletionTests.java
index 989100b..d0215db 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelCompletionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelCompletionTests.java
@@ -23,6 +23,7 @@
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.internal.codeassist.RelevanceConstants;
+import org.eclipse.jdt.internal.codeassist.impl.AssistOptions;
import junit.framework.*;
@@ -165,9 +166,9 @@
super.setUpSuite();
this.oldOptions = JavaCore.getOptions();
Hashtable<String, String> options = new Hashtable<>(this.oldOptions);
- options.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.DISABLED);
options.put(JavaCore.CODEASSIST_SUBWORD_MATCH, JavaCore.DISABLED);
JavaCore.setOptions(options);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, "false");
waitUntilIndexesReady();
}
@Override
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java
index 77b6350..6a9596b 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java
@@ -13,8 +13,6 @@
*******************************************************************************/
package org.eclipse.jdt.core.tests.model;
-import java.util.Hashtable;
-
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
@@ -25,6 +23,7 @@
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
+import org.eclipse.jdt.internal.codeassist.impl.AssistOptions;
import junit.framework.Test;
@@ -147,14 +146,12 @@
String str = this.workingCopies[0].getSource();
String completeBehind = "p";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
- Hashtable<String, String> tmpOld = JavaCore.getOptions();
- Hashtable<String, String> options = new Hashtable<>(tmpOld);
- options.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.DISABLED);
- JavaCore.setOptions(options);
+ String oldValue = System.getProperty(AssistOptions.PROPERTY_SubstringMatch);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, "false");
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
- JavaCore.setOptions(tmpOld);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, oldValue);
String expected = "provides[KEYWORD]{provides, null, null, provides, null, 49}";
assertResults(expected, requestor.getResults());
}
@@ -171,14 +168,12 @@
String str = this.workingCopies[0].getSource();
String completeBehind = "p";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
- Hashtable<String, String> tmpOld = JavaCore.getOptions();
- Hashtable<String, String> options = new Hashtable<>(tmpOld);
- options.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.ENABLED);
- JavaCore.setOptions(options);
+ String oldValue = System.getProperty(AssistOptions.PROPERTY_SubstringMatch);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, "true");
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
- JavaCore.setOptions(tmpOld);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, oldValue);
String expected = "exports[KEYWORD]{exports, null, null, exports, null, 19}\n"
+ "provides[KEYWORD]{provides, null, null, provides, null, 49}";
assertResults(expected, requestor.getResults());
@@ -196,14 +191,12 @@
String completeBehind = "u";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
- Hashtable<String, String> tmpOld = JavaCore.getOptions();
- Hashtable<String, String> options = new Hashtable<>(tmpOld);
- options.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.ENABLED);
- JavaCore.setOptions(options);
+ String oldValue = System.getProperty(AssistOptions.PROPERTY_SubstringMatch);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, "true");
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
- JavaCore.setOptions(tmpOld);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, oldValue);
String expected = "requires[KEYWORD]{requires, null, null, requires, null, 19}\n"
+ "uses[KEYWORD]{uses, null, null, uses, null, 49}";
@@ -243,17 +236,15 @@
String completeBehind = "mypa";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
- Hashtable<String, String> tmpOld = JavaCore.getOptions();
- Hashtable<String, String> options = new Hashtable<>(tmpOld);
- options.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.DISABLED);
- JavaCore.setOptions(options);
+ String oldValue = System.getProperty(AssistOptions.PROPERTY_SubstringMatch);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, "false");
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
String expected = "mypack1[PACKAGE_REF]{mypack1, mypack1, null, null, null, 49}\n"
+ "mypack2[PACKAGE_REF]{mypack2, mypack2, null, null, null, 49}\n"
+ "mypackage[PACKAGE_REF]{mypackage, mypackage, null, null, null, 49}";
assertResults(expected, requestor.getResults());
- JavaCore.setOptions(tmpOld);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, oldValue);
}
public void test486988_0008() throws JavaModelException {
@@ -289,15 +280,13 @@
String completeBehind = "mypack1 t";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
- Hashtable<String, String> tmpOld = JavaCore.getOptions();
- Hashtable<String, String> options = new Hashtable<>(tmpOld);
- options.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.DISABLED);
- JavaCore.setOptions(options);
+ String oldValue = System.getProperty(AssistOptions.PROPERTY_SubstringMatch);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, "false");
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
String expected = "to[KEYWORD]{to, null, null, to, null, 49}";
assertResults(expected, requestor.getResults());
- JavaCore.setOptions(tmpOld);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, oldValue);
}
public void test486988_0009() throws Exception {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests10.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests10.java
index c086841..863d50d 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests10.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests10.java
@@ -127,4 +127,31 @@
Signature.getUnionTypeBounds(typeSignature) // method name is wrong, it actually means: getIntersectionTypeBounds
);
}
+ public void testBug562382() throws CoreException {
+ this.wc = getWorkingCopy("/Resolve/src/X.java",
+ "class X {\n" +
+ " class Number {};\n" +
+ " class Integer extends Number {};\n" +
+ " interface Function<T, R> {\n" +
+ " R apply(T t);\n" +
+ " }\n" +
+ " Function<Number, Integer> fail() {\n" +
+ " return new Function<>() {\n" +
+ " @Override\n" +
+ " public Integer apply(Number t) {\n" +
+ " return null;\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "}"
+ );
+ String str = this.wc.getSource();
+ String selection = "Number";
+ int start = str.lastIndexOf(selection);
+ int length = selection.length();
+
+ IJavaElement[] selected = this.wc.codeSelect(start, length);
+ assertEquals(1, selected.length);
+ assertEquals("Number", selected[0].getElementName());
+ }
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SubstringCompletionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SubstringCompletionTests.java
index d46c6db..f6707a2 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SubstringCompletionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SubstringCompletionTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015, 2019 Gábor Kövesdán and others.
+ * Copyright (c) 2015, 2020 Gábor Kövesdán and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -13,11 +13,9 @@
*******************************************************************************/
package org.eclipse.jdt.core.tests.model;
-import java.util.Hashtable;
-
import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.codeassist.impl.AssistOptions;
import junit.framework.Test;
@@ -37,9 +35,7 @@
setUpProjectCompliance(COMPLETION_PROJECT, "1.8", true);
}
super.setUpSuite();
- Hashtable<String, String> options = new Hashtable<>(this.oldOptions);
- options.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.ENABLED);
- JavaCore.setOptions(options);
+ System.setProperty(AssistOptions.PROPERTY_SubstringMatch, "true");
}
@Override
public void tearDownSuite() throws Exception {
diff --git a/org.eclipse.jdt.core.tests.performance/.cvsignore b/org.eclipse.jdt.core.tests.performance/.cvsignore
deleted file mode 100644
index c5e82d7..0000000
--- a/org.eclipse.jdt.core.tests.performance/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index f351e5c..43157d0 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -3320,25 +3320,34 @@
private static char[][] decodeIgnoreOptionalProblemsFromFolders(String folders) {
StringTokenizer tokenizer = new StringTokenizer(folders, File.pathSeparator);
- char[][] result = new char[tokenizer.countTokens()][];
+ char[][] result = new char[2 * tokenizer.countTokens()][];
int count = 0;
while (tokenizer.hasMoreTokens()) {
String fileName = tokenizer.nextToken();
// relative folder names are created relative to the current user dir
File file = new File(fileName);
if (file.exists()) {
+ String absolutePath = file.getAbsolutePath();
+ result[count++] = absolutePath.toCharArray();
// if the file exists, we should try to use its canonical path
try {
- result[count++] = file.getCanonicalPath().toCharArray();
+ String canonicalPath = file.getCanonicalPath();
+ if (!absolutePath.equals(canonicalPath)) {
+ result[count++] = canonicalPath.toCharArray();
+ }
} catch (IOException e) {
- // if we got exception during canonicalization, fall back to the name that was specified
- result[count++] = fileName.toCharArray();
+ // ignore
}
} else {
// if the file does not exist, use the name that was specified
result[count++] = fileName.toCharArray();
}
}
+ if (count < result.length) {
+ char[][] shortened = new char[count][];
+ System.arraycopy(result, 0, shortened, 0, count);
+ result = shortened;
+ }
return result;
}
@@ -5358,7 +5367,7 @@
}
}
}
-protected final static boolean shouldIgnoreOptionalProblems(char[][] folderNames, char[] fileName) {
+public final static boolean shouldIgnoreOptionalProblems(char[][] folderNames, char[] fileName) {
if (folderNames == null || fileName == null) {
return false;
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocTag.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocTag.java
index 7b1f581..0faab36 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocTag.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocTag.java
@@ -16,7 +16,7 @@
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.JavadocSingleNameReference;
-import org.eclipse.jdt.internal.compiler.ast.RecordDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
@@ -132,11 +132,8 @@
switch (scope.kind) {
case Scope.CLASS_SCOPE:
if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
- boolean isRecordWithComponent = false;
- if( ((ClassScope)scope).referenceContext instanceof RecordDeclaration) {
- RecordDeclaration rd = (RecordDeclaration)((ClassScope)scope).referenceContext;
- isRecordWithComponent = rd.nRecordComponents >0 ;
- }
+ TypeDeclaration typeDecl = ((ClassScope)scope).referenceContext;
+ boolean isRecordWithComponent = typeDecl.isRecord() && typeDecl.nRecordComponents >0 ;
if (((ClassScope)scope).referenceContext.binding.isGenericType() || isRecordWithComponent) {
filteredTags[size++] = possibleTag;
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
index 92a40a3..cc7f502 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
@@ -55,13 +55,13 @@
"org.eclipse.jdt.core.codeComplete.discouragedReferenceCheck"; //$NON-NLS-1$
public static final String OPTION_CamelCaseMatch =
"org.eclipse.jdt.core.codeComplete.camelCaseMatch"; //$NON-NLS-1$
- public static final String OPTION_SubstringMatch =
- "org.eclipse.jdt.core.codeComplete.substringMatch"; //$NON-NLS-1$
public static final String OPTION_SubwordMatch =
"org.eclipse.jdt.core.codeComplete.subwordMatch"; //$NON-NLS-1$
public static final String OPTION_SuggestStaticImports =
"org.eclipse.jdt.core.codeComplete.suggestStaticImports"; //$NON-NLS-1$
+ public static final String PROPERTY_SubstringMatch = "jdt.codeCompleteSubstringMatch"; //$NON-NLS-1$
+
public static final String ENABLED = "enabled"; //$NON-NLS-1$
public static final String DISABLED = "disabled"; //$NON-NLS-1$
@@ -239,12 +239,8 @@
this.camelCaseMatch = false;
}
}
- if ((optionValue = optionsMap.get(OPTION_SubstringMatch)) != null) {
- if (ENABLED.equals(optionValue)) {
- this.substringMatch = true;
- } else if (DISABLED.equals(optionValue)) {
- this.substringMatch = false;
- }
+ if ("false".equals(System.getProperty(PROPERTY_SubstringMatch))) { //$NON-NLS-1$
+ this.substringMatch = false;
}
if ((optionValue = optionsMap.get(OPTION_SubwordMatch)) != null) {
if (ENABLED.equals(optionValue)) {
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
index fea7d23..2a8bb8b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
@@ -678,14 +678,6 @@
protected void consumeFormalParameter(boolean isVarArgs) {
if (this.indexOfAssistIdentifier() < 0) {
super.consumeFormalParameter(isVarArgs);
- if((!this.diet || this.dietInt != 0) && this.astPtr > -1) {
- Argument argument = (Argument) this.astStack[this.astPtr];
- if(argument.type == this.assistNode) {
- this.isOrphanCompletionNode = true;
- this.restartRecovery = true; // force to restart in recovery mode
- this.lastIgnoredToken = -1;
- }
- }
} else {
boolean isReceiver = this.intStack[this.intPtr--] == 0;
if (isReceiver) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 56a31e2..6eb0595 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -2316,6 +2316,9 @@
/** @since 3.22
* @noreference preview feature error */
int RecordStaticReferenceToOuterLocalVariable= PreviewRelated + 1755;
+ /** @since 3.22
+ * @noreference preview feature error */
+ int RecordCannotDefineRecordInLocalType= PreviewRelated + 1756;
/* records - end */
/* instanceof pattern: */
/** @since 3.22
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompactConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompactConstructorDeclaration.java
index e9a2150..88fa4f5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompactConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompactConstructorDeclaration.java
@@ -20,7 +20,7 @@
public class CompactConstructorDeclaration extends ConstructorDeclaration {
- public RecordDeclaration recordDeclaration;
+ public TypeDeclaration recordDeclaration;
public CompactConstructorDeclaration(CompilationResult compilationResult) {
super(compilationResult);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
index d57623a..c38ba90 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
@@ -180,6 +180,12 @@
return this.binding.isFinal();
return (this.modifiers & ClassFileConstants.AccFinal) != 0;
}
+@Override
+public StringBuffer print(int indent, StringBuffer output) {
+ if (this.isARecordComponent)
+ output.append("/* Implicit */"); //$NON-NLS-1$
+ return super.print(indent, output);
+}
@Override
public StringBuffer printStatement(int indent, StringBuffer output) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
index d600dfb..db8a662 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
@@ -403,6 +403,17 @@
@Override
public void resolve(BlockScope upperScope) {
+ if (this.condition != null && this.condition.containsPatternVariable()) {
+ this.condition.traverse(new ASTVisitor() {
+ @Override
+ public boolean visit(
+ InstanceOfExpression instanceOfExpression,
+ BlockScope sc) {
+ instanceOfExpression.resolvePatternVariable(upperScope);
+ return true; // We want to resolve all pattern variables if any inside the condition
+ }
+ }, upperScope);
+ }
// use the scope that will hold the init declarations
this.scope = (this.bits & ASTNode.NeededScope) != 0 ? new BlockScope(upperScope) : upperScope;
if (this.initializations != null)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
index 63939ca..3ce4c1a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
@@ -213,10 +213,8 @@
// @param tags
int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length;
for (int i = 0; i < paramTagsSize; i++) {
- if(scope.referenceContext instanceof RecordDeclaration) {
- RecordDeclaration rd = (RecordDeclaration)scope.referenceContext;
- if( rd.nRecordComponents > 0)
- break;
+ if(scope.referenceContext.nRecordComponents > 0) {
+ break;
}
JavadocSingleNameReference param = this.paramReferences[i];
scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
@@ -762,10 +760,7 @@
parameters = typeDeclaration.typeParameters;
typeVariables = typeDeclaration.binding.typeVariables;
modifiers = typeDeclaration.binding.modifiers;
- if (typeDeclaration instanceof RecordDeclaration) {
- RecordDeclaration recordDecl = (RecordDeclaration)typeDeclaration;
- recordParameters = recordDecl.getArgs();
- }
+ recordParameters = typeDeclaration.args;
break;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
index a811880..598ff74 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
@@ -201,13 +201,15 @@
if (this.arguments != null && this.arguments.length != 0)
return null;
ClassScope skope = this.scope.classScope();
- if (!(skope.referenceContext instanceof RecordDeclaration))
+ TypeDeclaration typeDecl = skope.referenceContext;
+ if (!typeDecl.isRecord())
return null;
- RecordDeclaration rd = (RecordDeclaration) skope.referenceContext;
- Argument[] args = rd.getArgs();
+ if (!(skope.referenceContext.isRecord()))
+ return null;
+ Argument[] args = typeDecl.args;
if (args == null || args.length == 0)
return null;
- for (Argument arg : rd.getArgs()) {
+ for (Argument arg : args) {
if (arg == null || arg.name == null)
continue;
if (CharOperation.equals(this.selector, arg.name)) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/RecordDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/RecordDeclaration.java
deleted file mode 100644
index 37470c2..0000000
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/RecordDeclaration.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2019, 2020 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
- * 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.internal.compiler.ast;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.ClassFile;
-import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
-import org.eclipse.jdt.internal.compiler.lookup.Scope;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
-import org.eclipse.jdt.internal.compiler.parser.Parser;
-
-public class RecordDeclaration extends TypeDeclaration {
-
- private Argument[] args;
- public int nRecordComponents;
- public boolean isLocalRecord;
- public static Set<String> disallowedComponentNames;
- static {
- disallowedComponentNames = new HashSet<>(6);
- disallowedComponentNames.add("clone"); //$NON-NLS-1$
- disallowedComponentNames.add("finalize"); //$NON-NLS-1$
- disallowedComponentNames.add("getClass"); //$NON-NLS-1$
- disallowedComponentNames.add("hashCode"); //$NON-NLS-1$
- disallowedComponentNames.add("notify"); //$NON-NLS-1$
- disallowedComponentNames.add("notifyAll");//$NON-NLS-1$
- disallowedComponentNames.add("toString"); //$NON-NLS-1$
- disallowedComponentNames.add("wait"); //$NON-NLS-1$
- }
- public RecordDeclaration(CompilationResult compilationResult) {
- super(compilationResult);
- this.modifiers |= ExtraCompilerModifiers.AccRecord;
- }
- public RecordDeclaration(TypeDeclaration t) {
- super(t.compilationResult);
- this.modifiers = t.modifiers | ExtraCompilerModifiers.AccRecord;
- this.modifiersSourceStart = t.modifiersSourceStart;
- this.annotations = t.annotations;
- this.name = t.name;
- this.superInterfaces = t.superInterfaces;
- this.fields = t.fields;
- this.methods = t.methods;
- this.memberTypes = t.memberTypes;
- this.binding = t.binding;
- this.scope = t.scope;
- this.initializerScope = t.initializerScope;
- this.staticInitializerScope = t.staticInitializerScope;
- this.ignoreFurtherInvestigation = t.ignoreFurtherInvestigation;
- this.maxFieldCount = t.maxFieldCount;
- this.declarationSourceStart = t.declarationSourceStart;
- this.declarationSourceEnd = t.declarationSourceEnd;
- this.bodyStart = t.bodyStart;
- this.bodyEnd = t.bodyEnd;
- this.missingAbstractMethods = t.missingAbstractMethods; // TODO: Investigate whether this is relevant.
- this.javadoc = t.javadoc;
- this.allocation = t.allocation;
- this.enclosingType = t.enclosingType;
- this.typeParameters = t.typeParameters;
- this.sourceStart = t.sourceStart;
- this.sourceEnd = t.sourceEnd;
- this.restrictedIdentifierStart = t.restrictedIdentifierStart;
- }
- public ConstructorDeclaration getConstructor(Parser parser) {
- if (this.methods != null) {
- for (int i = this.methods.length; --i >= 0;) {
- AbstractMethodDeclaration am;
- if ((am = this.methods[i]).isConstructor()) {
- if (!CharOperation.equals(am.selector, this.name)) {
- // the constructor was in fact a method with no return type
- // unless an explicit constructor call was supplied
- ConstructorDeclaration c = (ConstructorDeclaration) am;
- if (c.constructorCall == null || c.constructorCall.isImplicitSuper()) { //changed to a method
- MethodDeclaration m = parser.convertToMethodDeclaration(c, this.compilationResult);
- this.methods[i] = m;
- }
- } else {
- if (am instanceof CompactConstructorDeclaration) {
- CompactConstructorDeclaration ccd = (CompactConstructorDeclaration) am;
- ccd.recordDeclaration = this;
- if (ccd.arguments == null)
- ccd.arguments = this.args;
- return ccd;
- }
- // now we are looking at a "normal" constructor
- if (this.args == null && am.arguments == null)
- return (ConstructorDeclaration) am;
- }
- }
- }
- }
- /* At this point we can only say that there is high possibility that there is a constructor
- * If it is a CCD, then definitely it is there (except for empty one); else we need to check
- * the bindings to say that there is a canonical constructor. To take care at binding resolution time.
- */
- return null;
- }
-
- /** Returns an implicit canonical constructor, if any.
- */
- public static ConstructorDeclaration getImplicitCanonicalConstructor(AbstractMethodDeclaration[] methods) {
- if (methods == null)
- return null;
- for (AbstractMethodDeclaration am : methods) {
- if (am instanceof ConstructorDeclaration && (am.bits & (ASTNode.IsCanonicalConstructor | ASTNode.IsImplicit)) != 0)
- return (ConstructorDeclaration) am;
- }
- return null;
- }
- @Override
- public ConstructorDeclaration createDefaultConstructor(boolean needExplicitConstructorCall, boolean needToInsert) {
- //Add to method'set, the default constuctor that just recall the
- //super constructor with no arguments
- //The arguments' type will be positionned by the TC so just use
- //the default int instead of just null (consistency purpose)
-
- ConstructorDeclaration constructor = new ConstructorDeclaration(this.compilationResult);
- constructor.bits |= ASTNode.IsCanonicalConstructor | ASTNode.IsImplicit;
- constructor.selector = this.name;
-// constructor.modifiers = this.modifiers & ExtraCompilerModifiers.AccVisibilityMASK;
- constructor.modifiers = this.modifiers & ClassFileConstants.AccPublic;
- constructor.modifiers |= ClassFileConstants.AccPublic; // JLS 14 8.10.5
- constructor.arguments = this.args;
-
- constructor.declarationSourceStart = constructor.sourceStart =
- constructor.bodyStart = this.sourceStart;
- constructor.declarationSourceEnd =
- constructor.sourceEnd = constructor.bodyEnd = this.sourceStart - 1;
-
- //the super call inside the constructor
- if (needExplicitConstructorCall) {
- constructor.constructorCall = SuperReference.implicitSuperConstructorCall();
- constructor.constructorCall.sourceStart = this.sourceStart;
- constructor.constructorCall.sourceEnd = this.sourceEnd;
- }
- /* The body of the implicitly declared canonical constructor initializes each field corresponding
- * to a record component with the corresponding formal parameter in the order that they appear
- * in the record component list.*/
- List<Statement> statements = new ArrayList<>();
- int l = this.args != null ? this.args.length : 0;
- if (l > 0 && this.fields != null) {
- List<String> fNames = Arrays.stream(this.fields)
- .filter(f -> f.isARecordComponent)
- .map(f ->new String(f.name))
- .collect(Collectors.toList());
- for (int i = 0; i < l; ++i) {
- Argument arg = this.args[i];
- if (!fNames.contains(new String(arg.name)))
- continue;
- FieldReference lhs = new FieldReference(arg.name, 0);
- lhs.receiver = ThisReference.implicitThis();
- statements.add(new Assignment(lhs, new SingleNameReference(arg.name, 0), 0));
- }
- }
- constructor.statements = statements.toArray(new Statement[0]);
-
- //adding the constructor in the methods list: rank is not critical since bindings will be sorted
- if (needToInsert) {
- if (this.methods == null) {
- this.methods = new AbstractMethodDeclaration[] { constructor };
- } else {
- AbstractMethodDeclaration[] newMethods;
- System.arraycopy(
- this.methods,
- 0,
- newMethods = new AbstractMethodDeclaration[this.methods.length + 1],
- 1,
- this.methods.length);
- newMethods[0] = constructor;
- this.methods = newMethods;
- }
- }
- return constructor;
- }
-
- @Override
- public void generateCode(ClassFile enclosingClassFile) {
- super.generateCode(enclosingClassFile);
- }
- @Override
- public boolean isRecord() {
- return true;
- }
- @Override
- public StringBuffer printHeader(int indent, StringBuffer output) {
- printModifiers(this.modifiers, output);
- if (this.annotations != null) {
- printAnnotations(this.annotations, output);
- output.append(' ');
- }
-
- output.append("record "); //$NON-NLS-1$
- output.append(this.name);
- output.append('(');
- if (this.nRecordComponents > 0 && this.fields != null) {
- for (int i = 0; i < this.nRecordComponents; i++) {
- if (i > 0) output.append(", "); //$NON-NLS-1$
- output.append(this.fields[i].type.getTypeName()[0]);
- output.append(' ');
- output.append(this.fields[i].name);
- }
- }
- output.append(')');
- if (this.typeParameters != null) {
- output.append("<");//$NON-NLS-1$
- for (int i = 0; i < this.typeParameters.length; i++) {
- if (i > 0) output.append( ", "); //$NON-NLS-1$
- this.typeParameters[i].print(0, output);
- }
- output.append(">");//$NON-NLS-1$
- }
- if (this.superInterfaces != null && this.superInterfaces.length > 0) {
- output.append(" implements "); //$NON-NLS-1$
- for (int i = 0; i < this.superInterfaces.length; i++) {
- if (i > 0) output.append( ", "); //$NON-NLS-1$
- this.superInterfaces[i].print(0, output);
- }
- }
- return output;
- }
- @Override
- public StringBuffer printBody(int indent, StringBuffer output) {
- output.append(" {"); //$NON-NLS-1$
- if (this.memberTypes != null) {
- for (int i = 0; i < this.memberTypes.length; i++) {
- if (this.memberTypes[i] != null) {
- output.append('\n');
- this.memberTypes[i].print(indent + 1, output);
- }
- }
- }
- if (this.fields != null) {
- for (int fieldI = 0; fieldI < this.fields.length; fieldI++) {
- if (this.fields[fieldI] != null) {
- output.append('\n');
- if (fieldI < this.nRecordComponents)
- output.append("/* Implicit */"); //$NON-NLS-1$ //TODO BETA_JAVA14: Move this to FD?
- this.fields[fieldI].print(indent + 1, output);
- }
- }
- }
- if (this.methods != null) {
- for (int i = 0; i < this.methods.length; i++) {
- if (this.methods[i] != null) {
- output.append('\n');
- AbstractMethodDeclaration amd = this.methods[i];
- if (amd instanceof MethodDeclaration && (amd.bits & ASTNode.IsImplicit) != 0)
- output.append("/* Implicit */\n"); //$NON-NLS-1$// TODO BETA_JAVA14: Move this to MD?
- amd.print(indent + 1, output);
- }
- }
- }
- output.append('\n');
- return printIndent(indent, output).append('}');
- }
- public Argument[] getArgs() {
- return this.args;
- }
- public void setArgs(Argument[] args) {
- this.args = args;
- }
- public static void checkAndFlagRecordNameErrors(char[] typeName, ASTNode node, Scope skope) {
- if (CharOperation.equals(typeName, TypeConstants.RECORD_RESTRICTED_IDENTIFIER)) {
- if (skope.compilerOptions().sourceLevel == ClassFileConstants.JDK14) {
- skope.problemReporter().recordIsAReservedTypeName(node);
- }
- }
- }
- AbstractMethodDeclaration[] getMethod(char[] name1) {
- if (name1 == null || name1.length == 0 || this.methods == null)
- return null;
- List<AbstractMethodDeclaration> amList = new ArrayList<>(0);
- for (AbstractMethodDeclaration amd : this.methods) {
- if (CharOperation.equals(name1, amd.selector))
- amList.add(amd);
- }
- return amList.toArray(new AbstractMethodDeclaration[0]);
- }
-}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java
index bb16830..42b6e63 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java
@@ -542,6 +542,7 @@
*/
if (typeBbolean) {
for (int i = 0; i < resultExpressionsCount; ++i) {
+ if (this.originalValueResultExpressionTypes[i] == null) continue;
if (this.originalValueResultExpressionTypes[i].id == T_boolean) continue;
this.finalValueResultExpressionTypes[i] = env.computeBoxingType(this.originalValueResultExpressionTypes[i]);
this.resultExpressions.get(i).computeConversion(this.scope, this.finalValueResultExpressionTypes[i], this.originalValueResultExpressionTypes[i]);
@@ -604,7 +605,7 @@
resultNumeric = resultNumeric != null ? resultNumeric : check_nonconstant_int();
resultNumeric = resultNumeric != null ? resultNumeric : // one among the first few rules applied.
- getResultNumeric(typeSet, this.originalValueResultExpressionTypes); // check the rest
+ getResultNumeric(typeSet); // check the rest
typeSet = null; // hey gc!
for (int i = 0; i < resultExpressionsCount; ++i) {
this.resultExpressions.get(i).computeConversion(this.scope,
@@ -701,7 +702,7 @@
return areAllIntegerResultExpressionsConvertibleToTargetType(candidate) ?
candidate : null;
}
- private TypeBinding getResultNumeric(Set<TypeBinding> typeSet, TypeBinding[] armTypes) {
+ private TypeBinding getResultNumeric(Set<TypeBinding> typeSet) {
// note: if an expression has a type integer, then it will be a constant
// since non-constant integers are already processed before reaching here.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index e17e07c..84d5c75 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -24,6 +24,13 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.impl.*;
@@ -81,6 +88,23 @@
// 1.5 support
public TypeParameter[] typeParameters;
+ // 14 Records preview support
+ public Argument[] args;
+ public int nRecordComponents;
+ public boolean isLocalRecord;
+ public static Set<String> disallowedComponentNames;
+ static {
+ disallowedComponentNames = new HashSet<>(6);
+ disallowedComponentNames.add("clone"); //$NON-NLS-1$
+ disallowedComponentNames.add("finalize"); //$NON-NLS-1$
+ disallowedComponentNames.add("getClass"); //$NON-NLS-1$
+ disallowedComponentNames.add("hashCode"); //$NON-NLS-1$
+ disallowedComponentNames.add("notify"); //$NON-NLS-1$
+ disallowedComponentNames.add("notifyAll");//$NON-NLS-1$
+ disallowedComponentNames.add("toString"); //$NON-NLS-1$
+ disallowedComponentNames.add("wait"); //$NON-NLS-1$
+ }
+
public TypeDeclaration(CompilationResult compilationResult){
this.compilationResult = compilationResult;
}
@@ -280,6 +304,14 @@
}
}
+public static void checkAndFlagRecordNameErrors(char[] typeName, ASTNode node, Scope skope) {
+ if (CharOperation.equals(typeName, TypeConstants.RECORD_RESTRICTED_IDENTIFIER)) {
+ if (skope.compilerOptions().sourceLevel == ClassFileConstants.JDK14) {
+ skope.problemReporter().recordIsAReservedTypeName(node);
+ }
+ }
+}
+
/**
* Check for constructor vs. method with no return type.
* Answers true if at least one constructor is defined
@@ -325,7 +357,76 @@
return this.compilationResult;
}
+
+public ConstructorDeclaration createDefaultConstructorForRecord(boolean needExplicitConstructorCall, boolean needToInsert) {
+ //Add to method'set, the default constuctor that just recall the
+ //super constructor with no arguments
+ //The arguments' type will be positionned by the TC so just use
+ //the default int instead of just null (consistency purpose)
+
+ ConstructorDeclaration constructor = new ConstructorDeclaration(this.compilationResult);
+ constructor.bits |= ASTNode.IsCanonicalConstructor | ASTNode.IsImplicit;
+ constructor.selector = this.name;
+// constructor.modifiers = this.modifiers & ExtraCompilerModifiers.AccVisibilityMASK;
+ constructor.modifiers = this.modifiers & ClassFileConstants.AccPublic;
+ constructor.modifiers |= ClassFileConstants.AccPublic; // JLS 14 8.10.5
+ constructor.arguments = this.args;
+
+ constructor.declarationSourceStart = constructor.sourceStart =
+ constructor.bodyStart = this.sourceStart;
+ constructor.declarationSourceEnd =
+ constructor.sourceEnd = constructor.bodyEnd = this.sourceStart - 1;
+
+ //the super call inside the constructor
+ if (needExplicitConstructorCall) {
+ constructor.constructorCall = SuperReference.implicitSuperConstructorCall();
+ constructor.constructorCall.sourceStart = this.sourceStart;
+ constructor.constructorCall.sourceEnd = this.sourceEnd;
+ }
+/* The body of the implicitly declared canonical constructor initializes each field corresponding
+ * to a record component with the corresponding formal parameter in the order that they appear
+ * in the record component list.*/
+ List<Statement> statements = new ArrayList<>();
+ int l = this.args != null ? this.args.length : 0;
+ if (l > 0 && this.fields != null) {
+ List<String> fNames = Arrays.stream(this.fields)
+ .filter(f -> f.isARecordComponent)
+ .map(f ->new String(f.name))
+ .collect(Collectors.toList());
+ for (int i = 0; i < l; ++i) {
+ Argument arg = this.args[i];
+ if (!fNames.contains(new String(arg.name)))
+ continue;
+ FieldReference lhs = new FieldReference(arg.name, 0);
+ lhs.receiver = ThisReference.implicitThis();
+ statements.add(new Assignment(lhs, new SingleNameReference(arg.name, 0), 0));
+ }
+ }
+ constructor.statements = statements.toArray(new Statement[0]);
+
+ //adding the constructor in the methods list: rank is not critical since bindings will be sorted
+ if (needToInsert) {
+ if (this.methods == null) {
+ this.methods = new AbstractMethodDeclaration[] { constructor };
+ } else {
+ AbstractMethodDeclaration[] newMethods;
+ System.arraycopy(
+ this.methods,
+ 0,
+ newMethods = new AbstractMethodDeclaration[this.methods.length + 1],
+ 1,
+ this.methods.length);
+ newMethods[0] = constructor;
+ this.methods = newMethods;
+ }
+ }
+ return constructor;
+}
+
+
public ConstructorDeclaration createDefaultConstructor( boolean needExplicitConstructorCall, boolean needToInsert) {
+ if (this.isRecord())
+ return createDefaultConstructorForRecord(needExplicitConstructorCall, needToInsert);
//Add to method'set, the default constuctor that just recall the
//super constructor with no arguments
//The arguments' type will be positionned by the TC so just use
@@ -400,10 +501,10 @@
constructor.constructorCall.sourceEnd = this.sourceEnd;
if (argumentsLength > 0) {
- Expression[] args;
- args = constructor.constructorCall.arguments = new Expression[argumentsLength];
+ Expression[] args1;
+ args1 = constructor.constructorCall.arguments = new Expression[argumentsLength];
for (int i = argumentsLength; --i >= 0;) {
- args[i] = new SingleNameReference((baseName + i).toCharArray(), 0L);
+ args1[i] = new SingleNameReference((baseName + i).toCharArray(), 0L);
}
}
@@ -534,6 +635,42 @@
return null;
}
+/* only for records */
+public ConstructorDeclaration getConstructor(Parser parser) {
+ if (this.methods != null) {
+ for (int i = this.methods.length; --i >= 0;) {
+ AbstractMethodDeclaration am;
+ if ((am = this.methods[i]).isConstructor()) {
+ if (!CharOperation.equals(am.selector, this.name)) {
+ // the constructor was in fact a method with no return type
+ // unless an explicit constructor call was supplied
+ ConstructorDeclaration c = (ConstructorDeclaration) am;
+ if (c.constructorCall == null || c.constructorCall.isImplicitSuper()) { //changed to a method
+ MethodDeclaration m = parser.convertToMethodDeclaration(c, this.compilationResult);
+ this.methods[i] = m;
+ }
+ } else {
+ if (am instanceof CompactConstructorDeclaration) {
+ CompactConstructorDeclaration ccd = (CompactConstructorDeclaration) am;
+ ccd.recordDeclaration = this;
+ if (ccd.arguments == null)
+ ccd.arguments = this.args;
+ return ccd;
+ }
+ // now we are looking at a "normal" constructor
+ if (this.args == null && am.arguments == null)
+ return (ConstructorDeclaration) am;
+ }
+ }
+ }
+ }
+ /* At this point we can only say that there is high possibility that there is a constructor
+ * If it is a CCD, then definitely it is there (except for empty one); else we need to check
+ * the bindings to say that there is a canonical constructor. To take care at binding resolution time.
+ */
+ return null;
+}
+
/**
* Generic bytecode generation for type
*/
@@ -856,7 +993,7 @@
}
public boolean isRecord() {
- return false;
+ return (this.modifiers & ExtraCompilerModifiers.AccRecord) != 0;
}
/*
@@ -1059,6 +1196,18 @@
break;
}
output.append(this.name);
+ if (this.isRecord()) {
+ output.append('(');
+ if (this.nRecordComponents > 0 && this.fields != null) {
+ for (int i = 0; i < this.nRecordComponents; i++) {
+ if (i > 0) output.append(", "); //$NON-NLS-1$
+ output.append(this.fields[i].type.getTypeName()[0]);
+ output.append(' ');
+ output.append(this.fields[i].name);
+ }
+ }
+ output.append(')');
+ }
if (this.typeParameters != null) {
output.append("<");//$NON-NLS-1$
for (int i = 0; i < this.typeParameters.length; i++) {
@@ -1067,7 +1216,8 @@
}
output.append(">");//$NON-NLS-1$
}
- if (this.superclass != null) {
+
+ if (!this.isRecord() && this.superclass != null) {
output.append(" extends "); //$NON-NLS-1$
this.superclass.print(0, output);
}
@@ -1118,7 +1268,7 @@
this.scope.problemReporter().varIsReservedTypeName(this);
}
}
- RecordDeclaration.checkAndFlagRecordNameErrors(this.name, this, this.scope);
+ TypeDeclaration.checkAndFlagRecordNameErrors(this.name, this, this.scope);
// resolve annotations and check @Deprecated annotation
long annotationTagBits = sourceType.getAnnotationTagBits();
if ((annotationTagBits & TagBits.AnnotationDeprecated) == 0
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
index 185dda1..d15b4c0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
@@ -120,7 +120,7 @@
scope.problemReporter().varIsNotAllowedHere(this);
}
}
- RecordDeclaration.checkAndFlagRecordNameErrors(this.name, this, scope);
+ TypeDeclaration.checkAndFlagRecordNameErrors(this.name, this, scope);
}
@Override
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
index db75e3a..96e2bf0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
@@ -387,7 +387,7 @@
final int totalDimensions = dimensions + additionalDimensions;
Annotation [][] mergedAnnotations = new Annotation[totalDimensions][];
if (annotationsOnDimensions != null) {
- System.arraycopy(annotationsOnDimensions, 0, mergedAnnotations, 0, dimensions);
+ System.arraycopy(annotationsOnDimensions, 0, mergedAnnotations, 0, dimensions);
}
if (additionalAnnotations != null) {
for (int i = dimensions, j = 0; i < totalDimensions; i++, j++) {
@@ -532,7 +532,7 @@
} else {
reportInvalidType(scope);
}
- RecordDeclaration.checkAndFlagRecordNameErrors(getTypeName(0), this, scope);
+ TypeDeclaration.checkAndFlagRecordNameErrors(getTypeName(0), this, scope);
switch (type.problemId()) {
case ProblemReasons.NotFound :
case ProblemReasons.NotVisible :
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
index 2c9904b..c43e55c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
@@ -316,6 +316,10 @@
}
return this.resolvedType;
}
+ @Override
+ public boolean containsPatternVariable() {
+ return this.expression.containsPatternVariable();
+ }
@Override
public void traverse(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index a26218b..393398a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -1471,8 +1471,8 @@
case Opcodes.OPC_getfield :
if (returnTypeSize == 2) {
this.stackDepth++;
- pushTypeBinding(1, typeBinding);
}
+ pushTypeBinding(1, typeBinding);
break;
case Opcodes.OPC_getstatic :
if (returnTypeSize == 2) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
index 2c2bc23..bcb5ad2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
@@ -1815,8 +1815,7 @@
// treating extra storage
if (this.extra != null || otherInits.extra != null) {
- // four areas, but not all combinations are possible: only one of copyLimit/resetLimit will be > 0, takeLimit is exclusive to all others
- int takeLimit = 0; // [..takeLimit] : this is unreachable, take null info from other as-is
+ // three areas, but not all combinations are possible: only one of copyLimit/resetLimit will be > 0
int mergeLimit = 0; // [0..mergeLimit] : both flows have extra bits. Merge'em
int copyLimit = 0; // (mergeLimit..copyLimit] : only other has extra bits. Copy'em, sheding some doubt
int resetLimit = 0; // (copyLimit..resetLimit] : only this has extra bits. Shed doubt on them.
@@ -1899,87 +1898,95 @@
copyLimit = 0; // no need to carry inexisting nulls
mergeLimit = 0;
}
+ i = 0;
if (thisWasUnreachable) {
- // completely ignore unreachable info (don't shed any doubts on other)
- takeLimit = Math.max(resetLimit, mergeLimit);
- mergeLimit = 0;
- resetLimit = 0;
- }
- // compose nulls
- for (i = 0; i < takeLimit; i++) {
- this.extra[1 + 1][i] = otherInits.extra[1+1][i];
- this.extra[2 + 1][i] = otherInits.extra[2+1][i];
- this.extra[3 + 1][i] = otherInits.extra[3+1][i];
- this.extra[4 + 1][i] = otherInits.extra[4+1][i];
- }
- for (; i < mergeLimit; i++) {
- this.extra[1 + 1][i] = (a1=this.extra[1+1][i]) & (b1=otherInits.extra[1+1][i]) & (
- ((a2=this.extra[2+1][i]) & (((b2=otherInits.extra[2+1][i]) &
- ~(((a3=this.extra[3+1][i]) & (a4=this.extra[4+1][i])) ^ ((b3=otherInits.extra[3+1][i]) & (b4=otherInits.extra[4+1][i]))))
- |(a3 & a4 & (nb2=~b2))))
- |((na2=~a2) & ((b2 & b3 & b4)
- |(nb2 & ((na3=~a3) ^ b3)))));
- this.extra[2 + 1][i] = b2 & ((nb3=~b3) | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & (nb4=~b4))
- | a2 & (b2 | (na4=~a4) & b3 & (b4 | nb1) | na3 | na1);
- this.extra[3 + 1][i] = a3 & (na1 | a1 & na2 | b3 & (na4 ^ b4))
- | b3 & (nb1 | b1 & nb2);
- this.extra[4 + 1][i] = na3 & (nb1 & nb3 & b4
- | b1 & (nb2 & nb3 | a4 & b2 & nb4)
- | na1 & a4 & (nb3 | b1 & b2))
- | a3 & a4 & (b3 & b4 | b1 & nb2 | na1 & a2)
- | na2 & (nb1 & b4 | b1 & nb3 | na1 & a4) & nb2
- | a1 & (na3 & (nb3 & b4
- | b1 & b2 & b3 & nb4
- | na2 & (nb3 | nb2))
- | na2 & b3 & b4
- | a2 & (nb1 & b4 | a3 & na4 & b1) & nb3)
- |nb1 & b2 & b3 & b4;
- this.extra[IN][i] |= otherInits.extra[IN][i];
- this.extra[INN][i] |= otherInits.extra[INN][i];
- thisHasNulls = thisHasNulls ||
- this.extra[3][i] != 0 ||
- this.extra[4][i] != 0 ||
- this.extra[5][i] != 0 ;
- if (COVERAGE_TEST_FLAG) {
- if(CoverageTestId == 37) {
- this.extra[5][i] = ~0;
+ if (otherInits.extra != null) {
+ // take null info only from other, as much as available and without shedding doubt:
+ for (; i < mergeLimit; i++) {
+ this.extra[1 + 1][i] = otherInits.extra[1+1][i];
+ this.extra[2 + 1][i] = otherInits.extra[2+1][i];
+ this.extra[3 + 1][i] = otherInits.extra[3+1][i];
+ this.extra[4 + 1][i] = otherInits.extra[4+1][i];
}
}
- }
- for (; i < copyLimit; i++) {
- this.extra[1 + 1][i] = 0;
- this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i]) & (nb3 = ~(b3 = otherInits.extra[3 + 1][i]) | (nb1 = ~(b1 = otherInits.extra[1 + 1][i])));
- this.extra[3 + 1][i] = b3 & ((nb2 = ~b2) & (b4 = otherInits.extra[4 + 1][i]) | nb1) | b1 & nb2 & ~b4;
- this.extra[4 + 1][i] = (nb3 | nb2) & nb1 & b4 | b1 & nb3 & nb2;
- this.extra[IN][i] |= otherInits.extra[IN][i];
- this.extra[INN][i] |= otherInits.extra[INN][i];
- thisHasNulls = thisHasNulls ||
- this.extra[3][i] != 0 ||
- this.extra[4][i] != 0 ||
- this.extra[5][i] != 0;
- if (COVERAGE_TEST_FLAG) {
- if(CoverageTestId == 38) {
- this.extra[5][i] = ~0;
- }
+ // clear the remaining length of this.extra
+ for (; i < resetLimit; i++) {
+ this.extra[1 + 1][i] = 0;
+ this.extra[2 + 1][i] = 0;
+ this.extra[3 + 1][i] = 0;
+ this.extra[4 + 1][i] = 0;
}
- }
- for (; i < resetLimit; i++) {
- a1 = this.extra[1 + 1][i];
- this.extra[1 + 1][i] = 0;
- this.extra[2 + 1][i] = (a2 = this.extra[2 + 1][i]) & (na3 = ~(a3 = this.extra[3 + 1][i]) | (na1 = ~a1));
- this.extra[3 + 1][i] = a3 & ((na2 = ~a2) & (a4 = this.extra[4 + 1][i]) | na1) | a1 & na2 & ~a4;
- this.extra[4 + 1][i] = (na3 | na2) & na1 & a4 | a1 & na3 & na2;
- if (otherInits.extra != null && otherInits.extra[0].length > i) {
+ } else {
+ // compose nulls
+ for (; i < mergeLimit; i++) {
+ this.extra[1 + 1][i] = (a1=this.extra[1+1][i]) & (b1=otherInits.extra[1+1][i]) & (
+ ((a2=this.extra[2+1][i]) & (((b2=otherInits.extra[2+1][i]) &
+ ~(((a3=this.extra[3+1][i]) & (a4=this.extra[4+1][i])) ^ ((b3=otherInits.extra[3+1][i]) & (b4=otherInits.extra[4+1][i]))))
+ |(a3 & a4 & (nb2=~b2))))
+ |((na2=~a2) & ((b2 & b3 & b4)
+ |(nb2 & ((na3=~a3) ^ b3)))));
+ this.extra[2 + 1][i] = b2 & ((nb3=~b3) | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & (nb4=~b4))
+ | a2 & (b2 | (na4=~a4) & b3 & (b4 | nb1) | na3 | na1);
+ this.extra[3 + 1][i] = a3 & (na1 | a1 & na2 | b3 & (na4 ^ b4))
+ | b3 & (nb1 | b1 & nb2);
+ this.extra[4 + 1][i] = na3 & (nb1 & nb3 & b4
+ | b1 & (nb2 & nb3 | a4 & b2 & nb4)
+ | na1 & a4 & (nb3 | b1 & b2))
+ | a3 & a4 & (b3 & b4 | b1 & nb2 | na1 & a2)
+ | na2 & (nb1 & b4 | b1 & nb3 | na1 & a4) & nb2
+ | a1 & (na3 & (nb3 & b4
+ | b1 & b2 & b3 & nb4
+ | na2 & (nb3 | nb2))
+ | na2 & b3 & b4
+ | a2 & (nb1 & b4 | a3 & na4 & b1) & nb3)
+ |nb1 & b2 & b3 & b4;
this.extra[IN][i] |= otherInits.extra[IN][i];
this.extra[INN][i] |= otherInits.extra[INN][i];
- }
- thisHasNulls = thisHasNulls ||
- this.extra[3][i] != 0 ||
- this.extra[4][i] != 0 ||
- this.extra[5][i] != 0;
- if (COVERAGE_TEST_FLAG) {
- if(CoverageTestId == 39) {
- this.extra[5][i] = ~0;
+ thisHasNulls = thisHasNulls ||
+ this.extra[3][i] != 0 ||
+ this.extra[4][i] != 0 ||
+ this.extra[5][i] != 0 ;
+ if (COVERAGE_TEST_FLAG) {
+ if(CoverageTestId == 37) {
+ this.extra[5][i] = ~0;
+ }
+ }
+ }
+ for (; i < copyLimit; i++) {
+ this.extra[1 + 1][i] = 0;
+ this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i]) & (nb3 = ~(b3 = otherInits.extra[3 + 1][i]) | (nb1 = ~(b1 = otherInits.extra[1 + 1][i])));
+ this.extra[3 + 1][i] = b3 & ((nb2 = ~b2) & (b4 = otherInits.extra[4 + 1][i]) | nb1) | b1 & nb2 & ~b4;
+ this.extra[4 + 1][i] = (nb3 | nb2) & nb1 & b4 | b1 & nb3 & nb2;
+ this.extra[IN][i] |= otherInits.extra[IN][i];
+ this.extra[INN][i] |= otherInits.extra[INN][i];
+ thisHasNulls = thisHasNulls ||
+ this.extra[3][i] != 0 ||
+ this.extra[4][i] != 0 ||
+ this.extra[5][i] != 0;
+ if (COVERAGE_TEST_FLAG) {
+ if(CoverageTestId == 38) {
+ this.extra[5][i] = ~0;
+ }
+ }
+ }
+ for (; i < resetLimit; i++) {
+ a1 = this.extra[1 + 1][i];
+ this.extra[1 + 1][i] = 0;
+ this.extra[2 + 1][i] = (a2 = this.extra[2 + 1][i]) & (na3 = ~(a3 = this.extra[3 + 1][i]) | (na1 = ~a1));
+ this.extra[3 + 1][i] = a3 & ((na2 = ~a2) & (a4 = this.extra[4 + 1][i]) | na1) | a1 & na2 & ~a4;
+ this.extra[4 + 1][i] = (na3 | na2) & na1 & a4 | a1 & na3 & na2;
+ if (otherInits.extra != null && otherInits.extra[0].length > i) {
+ this.extra[IN][i] |= otherInits.extra[IN][i];
+ this.extra[INN][i] |= otherInits.extra[INN][i];
+ }
+ thisHasNulls = thisHasNulls ||
+ this.extra[3][i] != 0 ||
+ this.extra[4][i] != 0 ||
+ this.extra[5][i] != 0;
+ if (COVERAGE_TEST_FLAG) {
+ if(CoverageTestId == 39) {
+ this.extra[5][i] = ~0;
+ }
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
index 591075f..1d47311 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -42,7 +42,7 @@
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;import org.eclipse.jdt.internal.compiler.ast.RecordDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
@@ -105,7 +105,7 @@
anonymousType.tagBits |= TagBits.HierarchyHasProblems;
anonymousType.setSuperClass(getJavaLangObject());
} else if (supertype.erasure().id == TypeIds.T_JavaLangRecord) {
- if (!(this.referenceContext instanceof RecordDeclaration)) {
+ if (!(this.referenceContext.isRecord())) {
problemReporter().recordCannotExtendRecord(anonymousType, typeReference, supertype);
anonymousType.tagBits |= TagBits.HierarchyHasProblems;
anonymousType.setSuperClass(getJavaLangObject());
@@ -381,7 +381,7 @@
problemReporter().abstractMethodInConcreteClass(sourceType);
}
if (sourceType.isRecord()) {
- assert this.referenceContext instanceof RecordDeclaration;
+ assert this.referenceContext.isRecord();
methodBindings = sourceType.checkAndAddSyntheticRecordMethods(methodBindings, count);
count = methodBindings.length;
}
@@ -500,6 +500,11 @@
problemReporter().illegalLocalTypeDeclaration(this.referenceContext);
sourceType.modifiers = 0;
return;
+ } else if (sourceType.isRecord()) {
+ if (enclosingType != null && enclosingType.isLocalType()) {
+ problemReporter().illegalLocalTypeDeclaration(this.referenceContext);
+ return;
+ }
}
if (sourceType.isAnonymousType()) {
if (compilerOptions().complianceLevel < ClassFileConstants.JDK9)
@@ -1016,7 +1021,7 @@
} else if (superclass.erasure().id == TypeIds.T_JavaLangEnum) {
problemReporter().cannotExtendEnum(sourceType, superclassRef, superclass);
} else if (superclass.erasure().id == TypeIds.T_JavaLangRecord) {
- if (!(this.referenceContext instanceof RecordDeclaration)) {
+ if (!(this.referenceContext.isRecord())) {
problemReporter().recordCannotExtendRecord(sourceType, superclassRef, superclass);
} else {
return connectRecordSuperclass();
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 ff75ef8..564f75d 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
@@ -467,7 +467,9 @@
scope = new CompilationUnitScope(unit, this.globalOptions);
unitModule = unit.moduleDeclaration.setBinding(new SourceModuleBinding(moduleName, scope, this.root));
} else {
- unitModule = unit.module(this);
+ if (this.globalOptions.sourceLevel >= ClassFileConstants.JDK9) {
+ unitModule = unit.module(this);
+ }
scope = new CompilationUnitScope(unit, unitModule != null ? unitModule.environment : this);
}
scope.buildTypeBindings(accessRestriction);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 490ee18..4eb5754 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -76,7 +76,6 @@
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.RecordDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
@@ -147,7 +146,7 @@
this.fields = Binding.UNINITIALIZED_FIELDS;
this.methods = Binding.UNINITIALIZED_METHODS;
this.prototype = this;
- this.isRecordDeclaration = scope.referenceContext instanceof RecordDeclaration;
+ this.isRecordDeclaration = scope.referenceContext.isRecord();
computeId();
}
@@ -923,7 +922,24 @@
SyntheticMethodBinding accessMethod = null;
SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(selector);
- accessMethod = new SyntheticMethodBinding(this, getField(selector, true), index);
+ FieldBinding field = getField(selector, true);
+ accessMethod = new SyntheticMethodBinding(this, field, index);
+ AnnotationBinding[] annotations = field.getAnnotations();
+ if (annotations.length > 0) {
+ List<AnnotationBinding> list = new ArrayList<>();
+ for (AnnotationBinding binding : annotations) {
+ long bits = binding.getAnnotationType().getAnnotationTagBits();
+ if ((bits & TagBits.AnnotationForMethod) != 0
+ || (bits & TagBits.AnnotationTargetMASK) == 0) {
+ list.add(binding);
+ }
+ }
+ if (list.size() > 0) {
+ AnnotationBinding[] annots = new AnnotationBinding[list.size()];
+ annotations = list.toArray(annots);
+ accessMethod.setAnnotations(annotations, true);
+ }
+ }
if (accessors == null) {
this.synthetics[SourceTypeBinding.METHOD_EMUL].put(selector, accessors = new SyntheticMethodBinding[2]);
accessors[0] = accessMethod;
@@ -2990,7 +3006,7 @@
public void computeRecordComponents() {
if (!this.isRecordDeclaration || this.recordComponents != null)
return;
- Argument[] recComps = ((RecordDeclaration) this.scope.referenceContext).getArgs();
+ Argument[] recComps = this.scope.referenceContext.args;
List<FieldBinding> list = new ArrayList<>();
if (recComps != null && recComps.length > 0 && this.fields != null) {
List<String> recordComponentNames = new ArrayList<>(0);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
index 4e6df4f..bd24898 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
@@ -446,6 +446,9 @@
assert declaringSourceType.isRecord();
this.declaringClass = declaringSourceType;
this.modifiers = ClassFileConstants.AccPublic;
+ if (targetField.type instanceof TypeVariableBinding ||
+ targetField.type instanceof ParameterizedTypeBinding)
+ this.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
if (this.declaringClass.isStrictfp())
this.modifiers |= ClassFileConstants.AccStrictfp;
this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
index 1429127..68563bc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
@@ -128,8 +128,6 @@
long SE7AnnotationTargetMASK = AnnotationForType | AnnotationForField | AnnotationForMethod
| AnnotationForParameter | AnnotationForConstructor | AnnotationForLocalVariable
| AnnotationForAnnotationType | AnnotationForPackage;
- long AnnotationTargetMASK = SE7AnnotationTargetMASK | AnnotationTarget
- | AnnotationForTypeUse | AnnotationForTypeParameter | AnnotationForModule;
// 2-bits for retention (should check (tagBits & RetentionMask) == RuntimeRetention
long AnnotationSourceRetention = ASTNode.Bit45L;
long AnnotationClassRetention = ASTNode.Bit46L;
@@ -165,6 +163,9 @@
/** From Java 14 */
long AnnotationForRecordComponent = ASTNode.Bit31;
+ long AnnotationTargetMASK = SE7AnnotationTargetMASK | AnnotationTarget
+ | AnnotationForTypeUse | AnnotationForTypeParameter | AnnotationForModule | AnnotationForRecordComponent;
+
long AllStandardAnnotationsMask =
AnnotationTargetMASK
| AnnotationRetentionMASK
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index a00a7eb..653e39d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -973,7 +973,7 @@
private boolean expectTypeAnnotation = false;
private boolean reparsingLambdaExpression = false;
-private Map<RecordDeclaration, Integer[]> recordNestedMethodLevels;
+private Map<TypeDeclaration, Integer[]> recordNestedMethodLevels;
public Parser () {
// Caveat Emptor: For inheritance purposes and then only in very special needs. Only minimal state is initialized !
@@ -2706,7 +2706,7 @@
}
typeDecl.bodyStart = typeDecl.sourceEnd + 1;
if (isRecord) {
- typeDecl = new RecordDeclaration(typeDecl);
+ typeDecl.modifiers |= ExtraCompilerModifiers.AccRecord;
}
pushOnAstStack(typeDecl);
@@ -3556,8 +3556,10 @@
int recordIndex = -1;
Integer[] nestingTypeAndMethod = null;
for (int i = this.astPtr; i >= 0; --i) {
- if (this.astStack[i] instanceof RecordDeclaration) {
- RecordDeclaration node = (RecordDeclaration) this.astStack[i];
+ if (this.astStack[i] instanceof TypeDeclaration) {
+ TypeDeclaration node = (TypeDeclaration) this.astStack[i];
+ if (!node.isRecord())
+ continue;
nestingTypeAndMethod = this.recordNestedMethodLevels.get(node);
if (nestingTypeAndMethod != null) { // record declaration is done yet
recordIndex = i;
@@ -6603,6 +6605,7 @@
// TypeAnnotationsopt ::= $empty
pushOnTypeAnnotationLengthStack(0); // signal absence of @308 annotations.
}
+// BEGIN_AUTOGENERATED_REGION_CONSUME_RULE
// This method is part of an automatic generation : do NOT edit-modify
protected void consumeRule(int act) {
switch ( act ) {
@@ -8807,6 +8810,7 @@
}
}
+// END_AUTOGENERATED_REGION_CONSUME_RULE
protected void consumeVariableDeclaratorIdParameter () {
pushOnIntStack(1); // signal "normal" variable declarator id parameter.
}
@@ -10817,41 +10821,41 @@
dispatchDeclarationIntoRecordDeclaration(length);
}
- RecordDeclaration rd = (RecordDeclaration) this.astStack[this.astPtr];
- this.recordNestedMethodLevels.remove(rd);
+ TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+ this.recordNestedMethodLevels.remove(typeDecl);
if (!this.options.enablePreviewFeatures){
- problemReporter().previewFeatureNotEnabled(rd.sourceStart, rd.sourceEnd, "Records"); //$NON-NLS-1$
+ problemReporter().previewFeatureNotEnabled(typeDecl.sourceStart, typeDecl.sourceEnd, "Records"); //$NON-NLS-1$
} else {
if (this.options.isAnyEnabled(IrritantSet.PREVIEW)) {
- problemReporter().previewFeatureUsed(rd.sourceStart, rd.sourceEnd);
+ problemReporter().previewFeatureUsed(typeDecl.sourceStart, typeDecl.sourceEnd);
}
}
//convert constructor that do not have the type's name into methods
- ConstructorDeclaration cd = rd.getConstructor(this);
+ ConstructorDeclaration cd = typeDecl.getConstructor(this);
if (cd == null) {
/* create canonical constructor - check for the clash later at binding time */
- cd = rd.createDefaultConstructor(!(this.diet && this.dietInt == 0), true);
+ cd = typeDecl.createDefaultConstructor(!(this.diet && this.dietInt == 0), true);
} else {
cd.bits |= ASTNode.IsCanonicalConstructor;
}
if (this.scanner.containsAssertKeyword) {
- rd.bits |= ASTNode.ContainsAssertion;
+ typeDecl.bits |= ASTNode.ContainsAssertion;
}
- rd.addClinit();
- rd.bodyEnd = this.endStatementPosition;
- if (length == 0 && !containsComment(rd.bodyStart, rd.bodyEnd)) {
- rd.bits |= ASTNode.UndocumentedEmptyBlock;
+ typeDecl.addClinit();
+ typeDecl.bodyEnd = this.endStatementPosition;
+ if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
+ typeDecl.bits |= ASTNode.UndocumentedEmptyBlock;
}
TypeReference superClass = new QualifiedTypeReference(TypeConstants.JAVA_LANG_RECORD, new long[] {0});
superClass.bits |= ASTNode.IsSuperType;
- rd.superclass = superClass;
- rd.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+ typeDecl.superclass = superClass;
+ typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
}
protected void consumeRecordHeaderPart() {
// RecordHeaderPart ::= RecordHeaderName RecordHeader ClassHeaderImplementsopt
TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
- assert typeDecl instanceof RecordDeclaration;
+ assert typeDecl.isRecord();
// do nothing
}
protected void consumeRecordHeaderNameWithTypeParameters() {
@@ -10866,13 +10870,13 @@
// RecordComponentHeaderRightParen ::= ')'
int length = this.astLengthStack[this.astLengthPtr--];
this.astPtr -= length;
- RecordDeclaration rd = (RecordDeclaration) this.astStack[this.astPtr];
+ TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
int nestedMethodLevel = this.nestedMethod[this.nestedType];
- rd.isLocalRecord = nestedMethodLevel > 0;
- if (rd.isLocalRecord)
- rd.modifiers |= ClassFileConstants.AccStatic; // JLS 14 Sec 14.3
- this.recordNestedMethodLevels.put(rd, new Integer[] {this.nestedType, nestedMethodLevel});
- this.astStack[this.astPtr] = rd;
+ typeDecl.isLocalRecord = nestedMethodLevel > 0;
+ if (typeDecl.isLocalRecord)
+ typeDecl.modifiers |= ClassFileConstants.AccStatic; // JLS 14 Sec 14.3
+ this.recordNestedMethodLevels.put(typeDecl, new Integer[] {this.nestedType, nestedMethodLevel});
+ this.astStack[this.astPtr] = typeDecl;
// rd.sourceEnd = this.rParenPos;
if (length != 0) {
Argument[] args = new Argument[length];
@@ -10882,18 +10886,18 @@
args,
0,
length);
- rd.setArgs(args);
- convertToFields(rd, args);
+ typeDecl.args = args;
+ convertToFields(typeDecl, args);
}
- rd.bodyStart = this.rParenPos+1;
+ typeDecl.bodyStart = this.rParenPos+1;
this.listLength = 0; // reset this.listLength after having read all parameters
// recovery
if (this.currentElement != null){
- this.lastCheckPoint = rd.bodyStart;
- if (this.currentElement.parseTree() == rd) return;
+ this.lastCheckPoint = typeDecl.bodyStart;
+ if (this.currentElement.parseTree() == typeDecl) return;
}
}
-private void convertToFields(RecordDeclaration rd, Argument[] args) {
+private void convertToFields(TypeDeclaration typeDecl, Argument[] args) {
int length = args.length;
FieldDeclaration[] fields = new FieldDeclaration[length];
int nFields = 0;
@@ -10902,8 +10906,8 @@
Argument arg = args[i];
arg.bits |= ASTNode.IsRecordComponent;
String argName = new String(arg.name);
- if (RecordDeclaration.disallowedComponentNames.contains(argName)) {
- problemReporter().recordIllegalComponentNameInRecord(arg, rd);
+ if (TypeDeclaration.disallowedComponentNames.contains(argName)) {
+ problemReporter().recordIllegalComponentNameInRecord(arg, typeDecl);
continue;
}
if (argsSet.contains(argName)) {
@@ -10911,11 +10915,11 @@
continue;
}
if (arg.type.getLastToken() == TypeConstants.VOID) {
- problemReporter().recordComponentCannotBeVoid(rd, arg);
+ problemReporter().recordComponentCannotBeVoid(typeDecl, arg);
continue;
}
if (arg.isVarArgs() && i < max - 1)
- problemReporter().recordIllegalVararg(arg, rd);
+ problemReporter().recordIllegalVararg(arg, typeDecl);
argsSet.add(argName);
FieldDeclaration f = fields[nFields++] = createFieldDeclaration(arg.name, arg.sourceStart, arg.sourceEnd);
@@ -10968,8 +10972,8 @@
System.arraycopy(fields , 0, tmp, 0, nFields);
fields = tmp;
}
- rd.fields = fields;
- rd.nRecordComponents = fields.length;
+ typeDecl.fields = fields;
+ typeDecl.nRecordComponents = fields.length;
}
protected void consumeRecordHeader() {
//RecordHeader ::= '(' RecordComponentsopt RecordComponentHeaderRightParen
@@ -11208,7 +11212,7 @@
}
//arrays creation
- RecordDeclaration recordDecl = (RecordDeclaration) this.astStack[this.astPtr];
+ TypeDeclaration recordDecl = (TypeDeclaration) this.astStack[this.astPtr];
int nCreatedFields = recordDecl.fields != null ? recordDecl.fields.length : 0;
if (nFields != 0) {
FieldDeclaration[] tmp = new FieldDeclaration[(recordDecl.fields != null ? recordDecl.fields.length : 0) + nFields];
@@ -11278,11 +11282,11 @@
}
}
}
-private void checkForRecordMemberErrors(RecordDeclaration recordDecl, int nCreatedFields) {
- if (recordDecl.fields == null)
+private void checkForRecordMemberErrors(TypeDeclaration typeDecl, int nCreatedFields) {
+ if (typeDecl.fields == null)
return;
- for (int i = nCreatedFields; i < recordDecl.fields.length; i++) {
- FieldDeclaration f = recordDecl.fields[i];
+ for (int i = nCreatedFields; i < typeDecl.fields.length; i++) {
+ FieldDeclaration f = typeDecl.fields[i];
if (f != null && !f.isStatic()) {
if (f instanceof Initializer)
problemReporter().recordInstanceInitializerBlockInRecord((Initializer) f);
@@ -11290,9 +11294,9 @@
problemReporter().recordNonStaticFieldDeclarationInRecord(f);
}
}
- if (recordDecl.methods != null) {
- for (int i = 0; i < recordDecl.methods.length; i++) {
- AbstractMethodDeclaration method = recordDecl.methods[i];
+ if (typeDecl.methods != null) {
+ for (int i = 0; i < typeDecl.methods.length; i++) {
+ AbstractMethodDeclaration method = typeDecl.methods[i];
if ((method.modifiers & ClassFileConstants.AccNative) != 0) {
problemReporter().recordIllegalNativeModifierInRecord(method);
}
@@ -11473,8 +11477,9 @@
if (typeDecl.memberTypes != null) {
for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) {
- typeDecl.memberTypes[i].enclosingType = typeDecl;
- markNestedRecordStatic(typeDecl.memberTypes[i]);
+ TypeDeclaration memberType = typeDecl.memberTypes[i];
+ memberType.enclosingType = typeDecl;
+ markNestedRecordStatic(memberType);
}
}
}
@@ -11484,7 +11489,7 @@
* A nested record type is implicitly static.
* It is permitted for the declaration of a nested record type to redundantly specify the static modifier.
*/
- if (typeDeclaration instanceof RecordDeclaration)
+ if (typeDeclaration.isRecord())
typeDeclaration.modifiers |= ClassFileConstants.AccStatic;
}
protected void dispatchDeclarationIntoEnumDeclaration(int length) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
index addd30a..d68662e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
@@ -18,8 +18,9 @@
public interface ParserBasicInformation {
public final static int
+ // BEGIN_AUTOGENERATED_REGION
- ERROR_SYMBOL = 132,
+ ERROR_SYMBOL = 132,
MAX_NAME_LENGTH = 41,
NUM_STATES = 1197,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index 566bc23..5ec504b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -741,7 +741,7 @@
char c = line[i];
if (c == '\\') {
if (i < end) {
- if (lastPointer + 1 == i) {
+ if (lastPointer == i) {
lastPointer = i+1;
} else {
result.append(CharOperation.subarray(line, lastPointer == 0 ? start : lastPointer+1, i));
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
index 9f03708..379c8c7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
@@ -37,6 +37,7 @@
TokenNameCOMMENT_BLOCK = 1002,
TokenNameCOMMENT_JAVADOC = 1003;
+ // BEGIN_AUTOGENERATED_REGION
int TokenNameIdentifier = 21,
TokenNameabstract = 52,
TokenNameassert = 79,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index fdaea69..d9ae777 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -149,7 +149,6 @@
import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Receiver;
-import org.eclipse.jdt.internal.compiler.ast.RecordDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Reference;
import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
@@ -2859,6 +2858,8 @@
problemID = IProblem.CannotDefineAnnotationInLocalType;
} else if ((typeDeclaration.modifiers & ClassFileConstants.AccInterface) != 0) {
problemID = IProblem.CannotDefineInterfaceInLocalType;
+ } else if (typeDeclaration.isRecord()) {
+ problemID = IProblem.RecordCannotDefineRecordInLocalType;
}
if (problemID != 0) {
String[] arguments = new String[] {new String(typeDeclaration.name)};
@@ -11544,16 +11545,16 @@
stmt.sourceStart,
stmt.sourceEnd);
}
-public void recordIllegalComponentNameInRecord(Argument arg, RecordDeclaration rd) {
+public void recordIllegalComponentNameInRecord(Argument arg, TypeDeclaration typeDecl) {
if (!this.options.enablePreviewFeatures)
return;
this.handle(
IProblem.RecordIllegalComponentNameInRecord,
new String[] {
- new String(arg.name), new String(rd.name)
+ new String(arg.name), new String(typeDecl.name)
},
new String[] {
- new String(arg.name), new String(rd.name)
+ new String(arg.name), new String(typeDecl.name)
},
arg.sourceStart,
arg.sourceEnd);
@@ -11733,8 +11734,8 @@
recordDecl.sourceStart,
recordDecl.sourceEnd);
}
-public void recordIllegalVararg(Argument argType, RecordDeclaration recordDecl) {
- String[] arguments = new String[] {CharOperation.toString(argType.type.getTypeName()), new String(recordDecl.name)};
+public void recordIllegalVararg(Argument argType, TypeDeclaration typeDecl) {
+ String[] arguments = new String[] {CharOperation.toString(argType.type.getTypeName()), new String(typeDecl.name)};
this.handle(
IProblem.RecordIllegalVararg,
arguments,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index ab874bd..76ac8be 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -1048,6 +1048,7 @@
1753 = void is an invalid type for the component {0} of a record
1754 = The variable argument type {0} of the record {1} must be the last parameter
1755 = Cannot make a static reference to the non-static variable {0} from a local record
+1756 = A record declaration {0} is not allowed in a local inner class
1760 = The pattern variable {0} is not in scope in this location
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index 3aedfec..61541e6 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -3503,7 +3503,7 @@
recordDeclaration.typeParameters().add(convert(typeParameter));
}
}
- Argument[] args = ((org.eclipse.jdt.internal.compiler.ast.RecordDeclaration)typeDeclaration).getArgs();
+ Argument[] args = typeDeclaration.args;
if (args != null) {
for (Argument arg : args) {
recordDeclaration.recordComponents().add(convert(arg));
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 03bd8d1..f72fab4 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
@@ -2775,11 +2775,10 @@
* be found as a substring in a case-insensitive way.</p>
* <dl>
* <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.substringMatch"</code></dd>
- * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
- * <dt>Default:</dt><dd><code>"enabled"</code></dd>
* </dl>
* @since 3.12
- * @category CodeAssistOptionID
+ * @deprecated - this option has no effect
+ * @category DeprecatedOptionID
*/
public static final String CODEASSIST_SUBSTRING_MATCH = PLUGIN_ID + ".codeComplete.substringMatch"; //$NON-NLS-1$
/**
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
index 7feb5c0..e76f939 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
@@ -480,7 +480,7 @@
if ((TypeDeclaration.kind(typeInfo.getModifiers()) == TypeDeclaration.RECORD_DECL)) {
// The first choice constructor that takes CompilationResult as arg is not setting all the fields
// Hence, use the one that does
- type = new RecordDeclaration(type);
+ type.modifiers |= ExtraCompilerModifiers.AccRecord;
}
if (typeInfo.getEnclosingType() == null) {
if (typeHandle.isAnonymous()) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
index 65cdf03..031a67c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
@@ -111,7 +111,6 @@
defaultOptionsMap.put(JavaCore.CODEASSIST_FORBIDDEN_REFERENCE_CHECK, JavaCore.ENABLED);
defaultOptionsMap.put(JavaCore.CODEASSIST_DISCOURAGED_REFERENCE_CHECK, JavaCore.DISABLED);
defaultOptionsMap.put(JavaCore.CODEASSIST_CAMEL_CASE_MATCH, JavaCore.ENABLED);
- defaultOptionsMap.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.ENABLED);
defaultOptionsMap.put(JavaCore.CODEASSIST_SUBWORD_MATCH, JavaCore.ENABLED);
defaultOptionsMap.put(JavaCore.CODEASSIST_SUGGEST_STATIC_IMPORTS, JavaCore.ENABLED);
defaultOptionsMap.put(ChunkCache.CHUNK_CACHE_SIZE_MB, Double.toString(ChunkCache.CHUNK_CACHE_SIZE_MB_DEFAULT));
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index 6a3f3c9..6a6e1a2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -2490,7 +2490,6 @@
defaultOptionsMap.put(JavaCore.CODEASSIST_FORBIDDEN_REFERENCE_CHECK, JavaCore.ENABLED);
defaultOptionsMap.put(JavaCore.CODEASSIST_DISCOURAGED_REFERENCE_CHECK, JavaCore.DISABLED);
defaultOptionsMap.put(JavaCore.CODEASSIST_CAMEL_CASE_MATCH, JavaCore.ENABLED);
- defaultOptionsMap.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.ENABLED);
defaultOptionsMap.put(JavaCore.CODEASSIST_SUBWORD_MATCH, JavaCore.ENABLED);
defaultOptionsMap.put(JavaCore.CODEASSIST_SUGGEST_STATIC_IMPORTS, JavaCore.ENABLED);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index d12f2cf..09d13a6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -84,12 +84,14 @@
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.eval.IEvaluationContext;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.AutomaticModuleNaming;
import org.eclipse.jdt.internal.compiler.env.IModule;
import org.eclipse.jdt.internal.compiler.env.IModule.IModuleReference;
import org.eclipse.jdt.internal.compiler.env.IModule.IPackageExport;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.util.JRTUtil;
import org.eclipse.jdt.internal.compiler.util.ObjectVector;
@@ -1925,10 +1927,29 @@
{
manager.deltaState.addClasspathValidation(JavaProject.this);
}
+ checkExpireModule(propertyName, event.getOldValue(), event.getNewValue());
manager.resetProjectOptions(JavaProject.this);
JavaProject.this.resetCaches(); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=233568
}
}
+
+ void checkExpireModule(String propertyName, Object oldValue, Object newValue) {
+ if (propertyName.equals(JavaCore.COMPILER_SOURCE)) {
+ if (oldValue instanceof String && newValue instanceof String
+ && CompilerOptions.versionToJdkLevel((String) oldValue) >= ClassFileConstants.JDK9
+ && CompilerOptions.versionToJdkLevel((String) newValue) < ClassFileConstants.JDK9)
+ {
+ try {
+ // this is a change from modular to non-modular, forget the module if any:
+ IModuleDescription module = getModuleDescription();
+ if (module != null)
+ ((JavaElement)module).close();
+ } catch (JavaModelException e) {
+ // ignore
+ }
+ }
+ }
+ }
};
eclipsePreferences.addPreferenceChangeListener(this.preferencesChangeListener);
return eclipsePreferences;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
index 365a8ab..ba153df 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
@@ -326,6 +326,15 @@
@Override
public boolean hasCompilationUnit(String pkgName, String moduleName) {
if (scanContent()) {
+ if (!this.knownPackageNames.includes(pkgName)) {
+ // Don't waste time walking through the zip if we know that it doesn't
+ // contain a directory that matches pkgName
+ return false;
+ }
+
+ // Even if knownPackageNames contained the pkg we're looking for, we still need to verify
+ // that the package in this jar actually contains at least one .class file (since
+ // knownPackageNames includes empty packages)
for (Enumeration<? extends ZipEntry> e = this.zipFile.entries(); e.hasMoreElements(); ) {
String fileName = e.nextElement().getName();
if (fileName.startsWith(pkgName)
@@ -334,6 +343,7 @@
return true;
}
}
+
return false;
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java
index 7a8ee4c..1c14be8 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java
@@ -230,12 +230,13 @@
}
INameEnvironment environment = null;
try {
+ String fullyQualifiedName = declaringType == null? null : declaringType.getFullyQualifiedName('.');
this.context.evaluate(
codeSnippet.toCharArray(),
varTypeNames,
varNames,
localVariableModifiers,
- declaringType == null? null : declaringType.getFullyQualifiedName().toCharArray(),
+ fullyQualifiedName == null? null : fullyQualifiedName.toCharArray(),
isStatic,
isConstructorCall,
environment = getBuildNameEnvironment(),
diff --git a/org.eclipse.jdt.core/pom.xml b/org.eclipse.jdt.core/pom.xml
index f59c0f2..4acde60 100644
--- a/org.eclipse.jdt.core/pom.xml
+++ b/org.eclipse.jdt.core/pom.xml
@@ -73,7 +73,7 @@
<plugin>
<groupId>org.eclipse.tycho.extras</groupId>
<artifactId>tycho-custom-bundle-plugin</artifactId>
- <version>${tycho-extras.version}</version>
+ <version>${tycho.version}</version>
<executions>
<execution>
<id>antadapter</id>
diff --git a/org.eclipse.jdt.core/scripts/GenerateParserScript.java b/org.eclipse.jdt.core/scripts/GenerateParserScript.java
new file mode 100644
index 0000000..56cb92a
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/GenerateParserScript.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Bart Jacobs 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
+ *
+ */
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+
+public class GenerateParserScript {
+
+ private static void assertTrue(boolean b) { if (!b) throw new AssertionError(); }
+
+ public static void main(String[] args) throws IOException, InterruptedException {
+ File grammarDir = new File("../grammar");
+ File parserDir = new File("../compiler/org/eclipse/jdt/internal/compiler/parser");
+ String jikespg = System.getProperty("JIKESPG");
+ assertTrue(jikespg != null);
+
+ if (!jikespg.equals("JIKESPG_EXTERNAL")) {
+ // Run JikesPG
+ Process process = Runtime.getRuntime().exec(new String[] {jikespg, "java.g"}, null, grammarDir);
+ boolean ok = false;
+ try (BufferedReader jikespgOutput = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
+ for (;;) {
+ String line = jikespgOutput.readLine();
+ if (line == null)
+ break;
+ System.out.println(line);
+ if (line.equals("This grammar is LALR(1)."))
+ ok = true;
+ }
+ }
+ int exitCode = process.waitFor();
+ assertTrue(exitCode == 0);
+ if (!ok)
+ System.exit(1);
+ }
+
+ // Update parserNN.rsc and readableNames.props
+ File javadclFile = new File(grammarDir, "javadcl.java");
+ File javahdrFile = new File(grammarDir, "javahdr.java");
+ Parser.buildFilesFromLPG(javadclFile.toString(), javahdrFile.toString());
+ for (int i = 1; i <= 24; i++) {
+ String filename = "parser"+i+".rsc";
+ Files.move(new File(filename).toPath(), new File(parserDir, filename).toPath(), StandardCopyOption.REPLACE_EXISTING);
+ }
+ {
+ String filename = "readableNames.props";
+ Files.move(new File(filename).toPath(), new File(parserDir, filename).toPath(), StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ // Update TerminalTokens.java
+ File javasymFile = new File(grammarDir, "javasym.java");
+ File terminalTokensFile = new File(parserDir, "TerminalTokens.java");
+ String javasymText = new String(Files.readAllBytes(javasymFile.toPath())).replace("\r\n", "\n");
+ String terminalTokensText = new String(Files.readAllBytes(terminalTokensFile.toPath()));
+ {
+ String startTag = "// BEGIN_AUTOGENERATED_REGION\n";
+ int start = terminalTokensText.indexOf(startTag);
+ assertTrue(start >= 0);
+ start += startTag.length();
+ String terminalTokensProlog = terminalTokensText.substring(0, start);
+
+ String javasymProlog =
+ "interface javasym\n" +
+ "{\n" +
+ " public final static int\n" +
+ " ";
+ assertTrue(javasymText.startsWith(javasymProlog));
+ javasymText = javasymText.substring(javasymProlog.length());
+ javasymText = javasymText.replace(",\n ", ",\n\t\t\t\t\t\t\t");
+ javasymText = javasymText.replace("TokenName$eof", "TokenNameEOF");
+ javasymText = javasymText.replace("TokenName$error", "TokenNameERROR");
+ Files.write(terminalTokensFile.toPath(), (terminalTokensProlog + "\tint " + javasymText).getBytes());
+ }
+
+ // Update ParserBasicInformation.java
+ File javadefFile = new File(grammarDir, "javadef.java");
+ File parserBasicInformationFile = new File(parserDir, "ParserBasicInformation.java");
+ String javadefText = new String(Files.readAllBytes(javadefFile.toPath())).replace("\r\n", "\n");
+ String parserBasicInformationText = new String(Files.readAllBytes(parserBasicInformationFile.toPath()));
+ {
+ String startTag = "// BEGIN_AUTOGENERATED_REGION";
+ int start = parserBasicInformationText.indexOf(startTag);
+ assertTrue(start >= 0);
+ start += startTag.length();
+ String parserBasicInformationProlog = parserBasicInformationText.substring(0, start);
+
+ String javadefProlog =
+ "interface javadef\n" +
+ "{\n" +
+ " public final static int";
+ assertTrue(javadefText.startsWith(javadefProlog));
+ javadefText = javadefText.substring(javadefProlog.length());
+ javadefText = javadefText.replace("\n ", "\n\t\t\t\t\t");
+ javadefText = javadefText.replaceAll(" +", " ");
+ javadefText = javadefText.replace("};\n\n", "}\n");
+
+ Files.write(parserBasicInformationFile.toPath(), (parserBasicInformationProlog + javadefText).getBytes());
+ }
+
+ // Update method consumeRule in Parser.java
+ File parserFile = new File(parserDir, "Parser.java");
+ String parserText = new String(Files.readAllBytes(parserFile.toPath()));
+ File javaActionFile = new File(grammarDir, "JavaAction.java");
+ String javaActionText = new String(Files.readAllBytes(javaActionFile.toPath()))
+ .replace("\r\n", "\n").replace(" \n", "\n").replace(" \n", "\n");
+ {
+ String startTag = "// BEGIN_AUTOGENERATED_REGION_CONSUME_RULE\n";
+ String endTag = "// END_AUTOGENERATED_REGION_CONSUME_RULE\n";
+ int start = parserText.indexOf(startTag);
+ assertTrue(start >= 0);
+ start += startTag.length();
+ int end = parserText.indexOf(endTag, start);
+ assertTrue(end >= 0);
+
+ String newParserText = parserText.substring(0, start) + javaActionText + parserText.substring(end);
+
+ Files.write(parserFile.toPath(), newParserText.getBytes());
+ }
+
+ // Clean up JikesPG output files
+ Files.delete(javadclFile.toPath());
+ Files.delete(javahdrFile.toPath());
+ Files.delete(javaActionFile.toPath());
+ Files.delete(javasymFile.toPath());
+ Files.delete(javadefFile.toPath());
+ Files.delete(new File(grammarDir, "javaprs.java").toPath());
+ Files.delete(new File(grammarDir, "java.l").toPath());
+ }
+
+}
diff --git a/org.eclipse.jdt.core/scripts/build-parser.launch b/org.eclipse.jdt.core/scripts/build-parser.launch
new file mode 100644
index 0000000..55abf6b
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/build-parser.launch
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.ant.AntLaunchConfigurationType">
+ <booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
+ <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser" type="2"/> </resources>}"/>
+ <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+ <listEntry value="/eclipse.jdt.core/org.eclipse.jdt.core/scripts/build-parser.xml"/>
+ </listAttribute>
+ <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+ <listEntry value="1"/>
+ </listAttribute>
+ <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
+ <stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+ <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
+ <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.ant.internal.launching.remote.InternalAntRunner"/>
+ <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jdt.core"/>
+ <stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+ <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.jdt.core/scripts/build-parser.xml}"/>
+ <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-DJIKESPG=${JIKESPG}"/>
+ <stringAttribute key="process_factory_id" value="org.eclipse.ant.ui.remoteAntProcessFactory"/>
+</launchConfiguration>
diff --git a/org.eclipse.jdt.core/scripts/build-parser.xml b/org.eclipse.jdt.core/scripts/build-parser.xml
new file mode 100644
index 0000000..db649fc
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/build-parser.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2020 Stephan Hermmann 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
+ -->
+
+<project name="build-parser" default="build" basedir=".">
+
+ <!-- Usage hints:
+ 1. In your workspace please create a String Substitution named JIKESPG pointing to the jikespg executable.
+ See Preferences > Run/Debug > String Substitutions
+ 2. Invoke the script via build-parser.launch
+ -->
+ <target name="build">
+ <javac srcdir="${basedir}" includes="GenerateParserScript.java" destdir="${basedir}"
+ classpath="${basedir}/../bin"
+ debuglevel="lines,source"
+ source="1.8"
+ target="1.8">
+ <compilerarg/>
+ </javac>
+ <java classname="GenerateParserScript" classpath=".:${basedir}/../bin">
+ <sysproperty key="JIKESPG" value="${JIKESPG}"/>
+ </java>
+ </target>
+</project>
\ No newline at end of file