Design notes of and request for feedback on preliminary javax.lang.model support for records and sealed types

Joe Darcy joe.darcy at oracle.com
Wed Apr 17 20:19:12 UTC 2019


Hello,

I recently pushed preliminary  javax.lang.model support for records and 
sealed types to the "records-and-sealed" branch of amber:

     Initial support: 
http://hg.openjdk.java.net/amber/amber/rev/7eb4eb5792df
     Small bug fix: http://hg.openjdk.java.net/amber/amber/rev/20cd97aac3b0

Please send feedback on the API design.

The records document used as the basis for the API design is:

     http://cr.openjdk.java.net/~briangoetz/amber/datum.html

To summarize the language changes:

* records are a new kind of type
* records have a set of state components which drive a desugaring into 
assorted fields, methods, and constructors
* types, both classes and interfaces, can be sealed to only allow named 
permitted subtypes

The primary manifestations of the language changes in the API are:

* New ElementKind constants for a record and a state component. These 
are alongside existing element kinds of various flavors of types (ENUM, 
CLASS, ANNOTATION_TYPE, INTERFACE) and other constructs. There are 
supporting updates to the ElementKind.isClass() predicate and various 
ElementKindVisitor's.

* Two default methods are added to the TypeElement interface:
         default List<? extends VariableElement> getStateComponents()
         default List<? extends TypeMirror> getPermittedSubtypes()
As the basic model of types is changing, it is reasonable to update the 
TypeElement interface directly rather than placing analogous methods on 
the javax.lang.model.util.Elements supplemental utility interface. Note 
that permitted subtypes returns TypeMirrors rather than ElementTypes, 
consistent with TypeElement.getInterfaces doing the same.

* To avoid introducing a new top-level element category interface (like 
variable, type, package, module), state components are regarded as a new 
kind of VariableElement, a name-type pair with other ancillary 
information possibly available too.

* New javax.lang.model.element.Modifier enum constant for SEALED. The 
Elements utility interface gets an isSealed predicate that will also 
determine if a subtype has been non-sealed.

* Miscellaneous updates for consistency throughout the existing API, 
enclosed/enclosing relationships, etc.

Note that if "record" and "sealed" are handled as *restricted keywords*, 
then it is possible no explicit updates may be required to the 
SourceVersion.{isName, isKeyword, isIdentifier} methods 
(http://hg.openjdk.java.net/amber/amber/rev/bd78b65ff421).

Some known bugs/limitations:

* The API design discussed above implicitly calls for state components 
to be modeled separately from the fields or accessor methods they get 
desugared into. In the current implementation, the private fields are 
marked and used as the state components.

* The permitted types method always returns an empty list.

* Elements.isSealed() always returns false.

* A larger fractions of the fields and methods of a record are generated 
by the compiler than for other kinds of types. Therefore, I think it 
would be helpful if compiler implementations were more diligent about 
setting and tracking *origin* information for records. The origin

https://docs.oracle.com/en/java/javase/12/docs/api/java.compiler/javax/lang/model/util/Elements.Origin.html

of an element is whether it was declared explicitly (EXPLICIT), 
generated by the compiler under the mandate of a specification 
(MANDATED), or a compiler translation artifact (SYNTHETIC). One sample 
use of this information is the printing processor eliding output for 
methods like toString, equals, and hashCode if they are generated by the 
compiler.

Comments?

Thanks,

-Joe



More information about the amber-dev mailing list