Summary
-------
JEP 445 involves language changes and `javax.lang.model` needs supporting updates.
Problem
-------
Add and update API elements in `javax.lang.model` to support JEP 445's unnamed classes.
Solution
--------
Add a predicate to `TypeElement` to query for an unnamed class and update `Filer` to support creating unnamed classes.
Specification
-------------
diff --git a/src/java.compiler/share/classes/javax/annotation/processing/Filer.java b/src/java.compiler/share/classes/javax/annotation/processing/Filer.java
index a2e73ee8786..9ebcf2c5908 100644
--- a/src/java.compiler/share/classes/javax/annotation/processing/Filer.java
+++ b/src/java.compiler/share/classes/javax/annotation/processing/Filer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@ package javax.annotation.processing;
import javax.tools.JavaFileManager;
import javax.tools.*;
import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import java.io.IOException;
@@ -176,6 +177,13 @@ public interface Filer {
* <p>Creating a source file in or for an <em>unnamed</em> package in a <em>named</em>
* module is <em>not</em> supported.
*
+ * <p>If the environment is configured to support {@linkplain
+ * TypeElement#isUnnamed unnamed classes}, the name argument is
+ * used to provide the leading component of the name used for the
+ * output file. For example {@code filer.createSourceFile("Foo")}
+ * to create an unnamed class hosted in {@code Foo.java}. All
+ * unnamed classes must be in an unnamed package.
+ *
* @apiNote To use a particular {@linkplain
* java.nio.charset.Charset charset} to encode the contents of the
* file, an {@code OutputStreamWriter} with the chosen charset can
@@ -255,6 +263,13 @@ public interface Filer {
* <p>Creating a class file in or for an <em>unnamed</em> package in a <em>named</em>
* module is <em>not</em> supported.
*
+ * <p>If the environment is configured to support {@linkplain
+ * TypeElement#isUnnamed unnamed classes}, the name argument is
+ * used to provide the leading component of the name used for the
+ * output file. For example {@code filer.createClassFile("Foo")} to
+ * create an unnamed class hosted in {@code Foo.class}. All unnamed
+ * classes must be in an unnamed package.
+ *
* @apiNote To avoid subsequent errors, the contents of the class
* file should be compatible with the {@linkplain
* ProcessingEnvironment#getSourceVersion source version} being
diff --git a/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java b/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java
index 68df8920342..ab83acb344c 100644
diff --git a/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java b/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java
index 68df8920342..48bc4132eea 100644
--- a/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java
+++ b/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java
@@ -25,6 +25,8 @@
package javax.lang.model.element;
+import jdk.internal.javac.PreviewFeature;
+
import java.util.List;
import javax.lang.model.type.*;
import javax.lang.model.util.*;
@@ -147,7 +149,7 @@ public interface TypeElement extends Element, Parameterizable, QualifiedNameable
/**
* Returns the fully qualified name of this class or interface
* element. More precisely, it returns the <i>canonical</i> name.
- * For local and anonymous classes, which do not have canonical
+ * For local, anonymous, and {@linkplain #isUnnamed() unnamed} classes, which do not have canonical
* names, an {@linkplain Name##empty_name empty name} is
* returned.
*
@@ -163,6 +165,7 @@ public interface TypeElement extends Element, Parameterizable, QualifiedNameable
*
* @see Elements#getBinaryName
* @jls 6.7 Fully Qualified Names and Canonical Names
+ * @jls 7.3 Compilation Units
*/
Name getQualifiedName();
@@ -172,6 +175,10 @@ public interface TypeElement extends Element, Parameterizable, QualifiedNameable
* For an anonymous class, an {@linkplain Name##empty_name empty
* name} is returned.
*
+ * For an {@linkplain #isUnnamed() unnamed} class, a name matching
+ * the base name of the hosting file, minus any extension, is
+ * returned.
+ *
* @return the simple name of this class or interface,
* an empty name for an anonymous class
*
@@ -179,6 +186,22 @@ public interface TypeElement extends Element, Parameterizable, QualifiedNameable
@Override
Name getSimpleName();
+ /**
+ * {@return {@code true} if this is an unnamed class and {@code
+ * false} otherwise}
+ *
+ * @implSpec
+ * The default implementation of this method returns {@code false}.
+ *
+ * @jls 7.3 Compilation Units
+ * @since 21
+ */
+ @PreviewFeature(feature=PreviewFeature.Feature.UNNAMED_CLASSES,
+ reflective=true)
+ default boolean isUnnamed() {
+ return false;
+ }
+
/**
* Returns the direct superclass of this class or interface element.
* If this class or interface element represents an interface or the class