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