diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java b/java/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java index c4ff2100e0d6..1503fe37fb73 100644 --- a/java/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java +++ b/java/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java @@ -90,6 +90,7 @@ import com.sun.tools.javac.util.FatalError; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Pair; import java.io.File; import java.io.IOException; @@ -541,6 +542,7 @@ private void dropMethodsAndErrors(com.sun.tools.javac.util.Context ctx, Compilat return ; } hu.handled.add(cut); + Names names = Names.instance(ctx); Symtab syms = Symtab.instance(ctx); Trees trees = Trees.instance(BasicJavacTask.instance(ctx)); Types types = Types.instance(ctx); @@ -732,6 +734,13 @@ public Void visitClass(ClassTree node, Void p) { for (RecordComponent rc : clazz.sym.getRecordComponents()) { rc.type = error2Object(rc.type); scan(rc.accessorMeth, p); + if (rc.accessor == null) { + //the accessor is not created when the component type matches + //a non-arg j.l.Object method (which is a compile-time error) + //but the missing accessor will break Lower. + //initialize the field: + rc.accessor = new MethodSymbol(0, names.empty, new MethodType(com.sun.tools.javac.util.List.nil(), syms.errType, com.sun.tools.javac.util.List.nil(), syms.methodClass), clazz.sym); + } } for (JCTree def : clazz.defs) { boolean errorClass = isErroneousClass(def); diff --git a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorkerTest.java b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorkerTest.java index e2b0b3d0fb60..fd8d5bdc478a 100644 --- a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorkerTest.java +++ b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorkerTest.java @@ -2297,6 +2297,51 @@ public void testTypeTest() throws Exception { assertEquals(expected, file2Fixed); } + public void testWrongRecordComponent() throws Exception { + setSourceLevel("17"); + + Map file2Fixed = new HashMap<>(); + VanillaCompileWorker.fixedListener = (file, cut) -> { + try { + FileObject source = URLMapper.findFileObject(file.toUri().toURL()); + file2Fixed.put(FileUtil.getRelativePath(getRoot(), source), cut.toString()); + } catch (MalformedURLException ex) { + throw new IllegalStateException(ex); + } + }; + ParsingOutput result = runIndexing(Arrays.asList(compileTuple("test/Test.java", + "package test;\n" + + "public record Test(int wait) {\n" + + "}\n")), + Arrays.asList()); + + assertFalse(result.lowMemory); + assertTrue(result.success); + + Set createdFiles = new HashSet(); + + for (File created : result.createdFiles) { + createdFiles.add(getWorkDir().toURI().relativize(created.toURI()).getPath()); + } + + assertEquals(new HashSet(Arrays.asList("cache/s1/java/15/classes/test/Test.sig")), + createdFiles); + Map expected = Collections.singletonMap("test/Test.java", + "package test;\n" + + "\n" + + "public class Test {\n" + + " static {\n" + + " throw new java.lang.RuntimeException(\"Uncompilable code - compiler.err.illegal.record.component.name\");\n" + + " }\n" + + " \n" + + " public Test(int wait) {\n" + + " super();\n" + + " }\n" + + " private final int wait;\n" + + "}"); + assertEquals(expected, file2Fixed); + } + public static void noop() {} @Override