|
|
|
@ -1,5 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
* Copyright (c) 2005, 2024, 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
|
|
|
|
@ -35,6 +35,276 @@
|
|
|
|
|
* <p> Unless otherwise specified, methods in this package will throw
|
|
|
|
|
* a {@code NullPointerException} if given a {@code null} argument.
|
|
|
|
|
*
|
|
|
|
|
* @apiNote
|
|
|
|
|
*
|
|
|
|
|
* <h2 id=expectedEvolution>Expected visitor evolution</h2>
|
|
|
|
|
*
|
|
|
|
|
* As the Java programming language evolves, the visitor interfaces of
|
|
|
|
|
* the language model also evolve as do the concrete visitors in this
|
|
|
|
|
* package. A <a href="https://openjdk.org/jeps/12">preview language
|
|
|
|
|
* feature</a> in JDK <i>N</i> may have API elements added in the set
|
|
|
|
|
* of visitors for the preview language level. Such new elements are
|
|
|
|
|
* marked as reflective preview API. Any existing methods whose
|
|
|
|
|
* specification is updated to support the preview feature are
|
|
|
|
|
* <em>not</em> marked as preview.
|
|
|
|
|
*
|
|
|
|
|
* <p>The remainder of this note will show two examples of the API
|
|
|
|
|
* changes in the model and visitors that can be added to support a
|
|
|
|
|
* language feature. The examples will use additions to the elements
|
|
|
|
|
* portion of the language model, but the updates to visitors for
|
|
|
|
|
* types or annotation values would be analogous.
|
|
|
|
|
*
|
|
|
|
|
* Two distinct cases are:
|
|
|
|
|
* <ul>
|
|
|
|
|
*
|
|
|
|
|
* <li>the preview language construct has a corresponding new modeling
|
|
|
|
|
* interface and a concomitant new kind constant, such as a new {@link
|
|
|
|
|
* javax.lang.model.element.ElementKind} constant
|
|
|
|
|
*
|
|
|
|
|
* <li>the preview language construct only triggers the introduction
|
|
|
|
|
* of a new kind <em>without</em> a new modeling interface
|
|
|
|
|
*
|
|
|
|
|
* </ul>
|
|
|
|
|
*
|
|
|
|
|
* If a preview language feature is withdrawn rather than evolving to
|
|
|
|
|
* a permanent platform feature, the API elements associated with the
|
|
|
|
|
* feature are expected to be removed. The examples below outline the
|
|
|
|
|
* API changes expected when a preview feature becomes a permanent
|
|
|
|
|
* feature.
|
|
|
|
|
*
|
|
|
|
|
* <h3 id=topLevelLangConstruct>Adding visitor support for a
|
|
|
|
|
* top-level language construct</h3>
|
|
|
|
|
*
|
|
|
|
|
* Consider a new language feature, preview feature 1, in JDK <i>N</i>. This
|
|
|
|
|
* feature has a top-level element interface to model it:
|
|
|
|
|
*
|
|
|
|
|
* <pre>
|
|
|
|
|
* package javax.lang.model.element;
|
|
|
|
|
* /**
|
|
|
|
|
* * Represents a preview feature 1.
|
|
|
|
|
* *
|
|
|
|
|
* * @since N
|
|
|
|
|
* */
|
|
|
|
|
* public interface PreviewFeature1Element extends Element {
|
|
|
|
|
* // Methods to retrieve information specific to the preview feature...
|
|
|
|
|
* }
|
|
|
|
|
* </pre>
|
|
|
|
|
* A new element kind would also be introduced to model such a feature:
|
|
|
|
|
*
|
|
|
|
|
* <pre>
|
|
|
|
|
* // Sample diff of ElementKind.java
|
|
|
|
|
* + /**
|
|
|
|
|
* + * A preview feature 1.
|
|
|
|
|
* + * @since N
|
|
|
|
|
* + */
|
|
|
|
|
* + PREVIEW_FEATURE_1,
|
|
|
|
|
* </pre>
|
|
|
|
|
*
|
|
|
|
|
* A {@code default} method is added to {@code ElementVisitor} to accommodate the new construct:
|
|
|
|
|
* <pre>
|
|
|
|
|
* // Sample diff for ElementVisitor.java
|
|
|
|
|
* + /**
|
|
|
|
|
* + * Visits a preview feature 1.
|
|
|
|
|
* + *
|
|
|
|
|
* + * @implSpec The default implementation visits a {@code
|
|
|
|
|
* + * PreviewFeature1Element} by calling {@code visitUnknown(e, p)}.
|
|
|
|
|
* + *
|
|
|
|
|
* + * @param e the element to visit
|
|
|
|
|
* + * @param p a visitor-specified parameter
|
|
|
|
|
* + * @return a visitor-specified result
|
|
|
|
|
* + * @since N
|
|
|
|
|
* + */
|
|
|
|
|
* + default R visitPreviewFeature1(PreviewFeature1Element e, P p) {
|
|
|
|
|
* + return visitUnknown(e, p);
|
|
|
|
|
* + }
|
|
|
|
|
* </pre>
|
|
|
|
|
*
|
|
|
|
|
* Given the {@code default} method on the visitor interface, the
|
|
|
|
|
* preview visitor classes need to override this method and take an
|
|
|
|
|
* action appropriate for the visitor's semantics:
|
|
|
|
|
*
|
|
|
|
|
* <pre>
|
|
|
|
|
* // Sample diff for AbstractElementVisitorPreview.java
|
|
|
|
|
* // Re-abstract visitPreviewFeature1.
|
|
|
|
|
* + /**
|
|
|
|
|
* + * {@inheritDoc ElementVisitor}
|
|
|
|
|
* + *
|
|
|
|
|
* + * @implSpec Visits a {@code PreviewFeature1Element} in a manner
|
|
|
|
|
* + * defined by a subclass.
|
|
|
|
|
* + *
|
|
|
|
|
* + * @param e {@inheritDoc ElementVisitor}
|
|
|
|
|
* + * @param p {@inheritDoc ElementVisitor}
|
|
|
|
|
* + * @return a visitor-specified result
|
|
|
|
|
* + * @since N
|
|
|
|
|
* + */
|
|
|
|
|
* + @Override
|
|
|
|
|
* + public abstract R visitPreviewFeature1(PreviewFeature1Element e, P p);
|
|
|
|
|
*
|
|
|
|
|
* // Sample diff for ElementKindVisitorPreview.java
|
|
|
|
|
* // Take the default action for a preview feature 1.
|
|
|
|
|
* +
|
|
|
|
|
* + /**
|
|
|
|
|
* + * {@inheritDoc ElementVisitor}
|
|
|
|
|
* + *
|
|
|
|
|
* + * @implSpec This implementation calls {@code defaultAction}.
|
|
|
|
|
* + *
|
|
|
|
|
* + * @param e {@inheritDoc ElementVisitor}
|
|
|
|
|
* + * @param p {@inheritDoc ElementVisitor}
|
|
|
|
|
* + * @return the result of {@code defaultAction}
|
|
|
|
|
* + * @since N
|
|
|
|
|
* + */
|
|
|
|
|
* + @Override
|
|
|
|
|
* + public R visitPreviewFeature1(PreviewFeature1Element e, P p) {
|
|
|
|
|
* + return defaultAction(e, p);
|
|
|
|
|
* + }
|
|
|
|
|
*
|
|
|
|
|
* // Sample diff for ElementScannerPreview.java
|
|
|
|
|
* // Scan the enclosed elements of a preview feature 1.
|
|
|
|
|
* +
|
|
|
|
|
* + /**
|
|
|
|
|
* + * {@inheritDoc ElementVisitor}
|
|
|
|
|
* + *
|
|
|
|
|
* + * @implSpec This implementation scans the enclosed elements.
|
|
|
|
|
* + *
|
|
|
|
|
* + * @param e {@inheritDoc ElementVisitor}
|
|
|
|
|
* + * @param p {@inheritDoc ElementVisitor}
|
|
|
|
|
* + * @return {@inheritDoc ElementScanner6}
|
|
|
|
|
* + * @since N
|
|
|
|
|
* + */
|
|
|
|
|
* + @Override
|
|
|
|
|
* + public R visitPreviewFeature1(PreviewFeature1Element e, P p) {
|
|
|
|
|
* + return scan(e.getEnclosedElements(), p);
|
|
|
|
|
* + }
|
|
|
|
|
*
|
|
|
|
|
* // Sample diff for SimpleElementVisitorPreview.java
|
|
|
|
|
* // Take the default action for a preview feature 1.
|
|
|
|
|
* + /**
|
|
|
|
|
* + * {@inheritDoc ElementVisitor}
|
|
|
|
|
* + *
|
|
|
|
|
* + * @implSpec Visits a {@code PreviewFeature1Element} by calling
|
|
|
|
|
* + * {@code defaultAction}.
|
|
|
|
|
* + *
|
|
|
|
|
* + * @param e {@inheritDoc ElementVisitor}
|
|
|
|
|
* + * @param p {@inheritDoc ElementVisitor}
|
|
|
|
|
* + * @return {@inheritDoc ElementVisitor}
|
|
|
|
|
* + * @since N
|
|
|
|
|
* + */
|
|
|
|
|
* + @Override
|
|
|
|
|
* + public R visitPreviewFeature1(PreviewFeature1Element e, P p) {
|
|
|
|
|
* + return defaultAction(e, p);
|
|
|
|
|
* + }
|
|
|
|
|
* </pre>
|
|
|
|
|
*
|
|
|
|
|
* When preview feature 1 exits preview in JDK (<i>N+k</i>), a set of
|
|
|
|
|
* visitors for language level (<i>N+k</i>) would be added. The
|
|
|
|
|
* methods operating over the feature would be moved from the preview
|
|
|
|
|
* visitors to the new language level (<i>N+k</i>) visitors. Each
|
|
|
|
|
* preview visitor would then have its direct superclass changed to
|
|
|
|
|
* the new corresponding (<i>N+k</i>) visitor.
|
|
|
|
|
*
|
|
|
|
|
* <h3 id=newKindLangConstruct>Adding visitor support for a language
|
|
|
|
|
* construct that is a new kind of an existing construct</h3>
|
|
|
|
|
*
|
|
|
|
|
* Consider a new language feature, preview feature 2, in JDK
|
|
|
|
|
* <i>N</i>. This feature has a new element kind <em>without</em> a
|
|
|
|
|
* new top-level element interface needed to model it. Concretely,
|
|
|
|
|
* assume a preview feature 2 is a new kind of variable; the changes
|
|
|
|
|
* would be analogous if the feature were a new kind of executable
|
|
|
|
|
* instead or new kind of another existing top-level construct. In
|
|
|
|
|
* that case, the API changes are more limited:
|
|
|
|
|
*
|
|
|
|
|
* <pre>
|
|
|
|
|
* // Sample diff for ElementKind.java
|
|
|
|
|
* + /**
|
|
|
|
|
* + * A preview feature 2.
|
|
|
|
|
* + * @since N
|
|
|
|
|
* + */
|
|
|
|
|
* + PREVIEW_FEATURE_2,
|
|
|
|
|
* ...
|
|
|
|
|
* // Update existing methods as needed
|
|
|
|
|
* public boolean isVariable() {
|
|
|
|
|
* return switch(this) {
|
|
|
|
|
* case ENUM_CONSTANT, FIELD, PARAMETER,
|
|
|
|
|
* LOCAL_VARIABLE, EXCEPTION_PARAMETER, RESOURCE_VARIABLE,
|
|
|
|
|
* - BINDING_VARIABLE -> true;
|
|
|
|
|
* + BINDING_VARIABLE, PREVIEW_FEATURE_2 -> true;
|
|
|
|
|
* default -> false;
|
|
|
|
|
* };
|
|
|
|
|
* }
|
|
|
|
|
* </pre>
|
|
|
|
|
*
|
|
|
|
|
* The kind visitors need support for the new variety of element:
|
|
|
|
|
* <pre>
|
|
|
|
|
* // Update visitVariable in ElementKindVisitor6:
|
|
|
|
|
* ...
|
|
|
|
|
* * @implSpec This implementation dispatches to the visit method for
|
|
|
|
|
* * the specific {@linkplain ElementKind kind} of variable, {@code
|
|
|
|
|
* * ENUM_CONSTANT}, {@code EXCEPTION_PARAMETER}, {@code FIELD},
|
|
|
|
|
* - * {@code LOCAL_VARIABLE}, {@code PARAMETER}, or {@code RESOURCE_VARIABLE}.
|
|
|
|
|
* + * {@code LOCAL_VARIABLE}, {@code PARAMETER}, {@code RESOURCE_VARIABLE},
|
|
|
|
|
* + * or {@code PREVIEW_FEATURE_2}.
|
|
|
|
|
* *
|
|
|
|
|
* * @param e {@inheritDoc ElementVisitor}
|
|
|
|
|
* * @param p {@inheritDoc ElementVisitor}
|
|
|
|
|
* * @return the result of the kind-specific visit method
|
|
|
|
|
* */
|
|
|
|
|
* @Override
|
|
|
|
|
* public R visitVariable(VariableElement e, P p) {
|
|
|
|
|
* ...
|
|
|
|
|
* case BINDING_VARIABLE:
|
|
|
|
|
* return visitVariableAsBindingVariable(e, p);
|
|
|
|
|
*
|
|
|
|
|
* + case PREVIEW_FEATURE_2:
|
|
|
|
|
* + return visitVariableAsPreviewFeature2(e, p);
|
|
|
|
|
* +
|
|
|
|
|
* default:
|
|
|
|
|
* throw new AssertionError("Bad kind " + k + " for VariableElement" + e);
|
|
|
|
|
* ...
|
|
|
|
|
* + /**
|
|
|
|
|
* + * Visits a {@code PREVIEW_FEATURE_2} variable element.
|
|
|
|
|
* + *
|
|
|
|
|
* + * @implSpec This implementation calls {@code visitUnknown}.
|
|
|
|
|
* + *
|
|
|
|
|
* + * @param e the element to visit
|
|
|
|
|
* + * @param p a visitor-specified parameter
|
|
|
|
|
* + * @return the result of {@code visitUnknown}
|
|
|
|
|
* + *
|
|
|
|
|
* + * @since N
|
|
|
|
|
* + */
|
|
|
|
|
* + public R visitVariableAsPreviewFeature2(VariableElement e, P p) {
|
|
|
|
|
* + return visitUnknown(e, p);
|
|
|
|
|
* + }
|
|
|
|
|
* </pre>
|
|
|
|
|
*
|
|
|
|
|
* The preview element kind visitor in turn overrides {@code
|
|
|
|
|
* visitVariableAsPreviewFeature2}:
|
|
|
|
|
* <pre>
|
|
|
|
|
* // Sample diff for ElementKindVisitorPreview:
|
|
|
|
|
* + /**
|
|
|
|
|
* + * {@inheritDoc ElementKindVisitor6}
|
|
|
|
|
* + *
|
|
|
|
|
* + * @implSpec This implementation calls {@code defaultAction}.
|
|
|
|
|
* + *
|
|
|
|
|
* + * @param e {@inheritDoc ElementKindVisitor6}
|
|
|
|
|
* + * @param p {@inheritDoc ElementKindVisitor6}
|
|
|
|
|
* + * @return the result of {@code defaultAction}
|
|
|
|
|
* + *
|
|
|
|
|
* + * @since N
|
|
|
|
|
* + */
|
|
|
|
|
* + @Override
|
|
|
|
|
* + public R visitVariableAsPreviewFeature2(VariableElement e, P p) {
|
|
|
|
|
* + return defaultAction(e, p);
|
|
|
|
|
* + }
|
|
|
|
|
* </pre>
|
|
|
|
|
*
|
|
|
|
|
* As in the case where a new interface is introduced, when preview
|
|
|
|
|
* feature 2 exits preview in JDK (<i>N+k</i>), a set of visitors for
|
|
|
|
|
* language level (<i>N+k</i>) would be added. The methods operating
|
|
|
|
|
* over the new feature in the kind visitors would be moved from the
|
|
|
|
|
* preview visitors to new language level (<i>N+k</i>) visitors. Each
|
|
|
|
|
* preview visitor would then have its direct superclass changed to
|
|
|
|
|
* the new corresponding (<i>N+k</i>) visitor.
|
|
|
|
|
*
|
|
|
|
|
* @since 1.6
|
|
|
|
|
*
|
|
|
|
|
* @see <a href="https://jcp.org/en/jsr/detail?id=269">
|
|
|
|
|