EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/RecordDeclaration.java
1/*******************************************************************************
2 * Copyright (c) 2019, 2021 IBM Corporation and others.
3 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
10 * Contributors:
11 *     IBM Corporation - initial API and implementation
12 *******************************************************************************/
13
14package org.eclipse.jdt.core.dom;
15
16import java.util.ArrayList;
17import java.util.Iterator;
18import java.util.List;
19
20/**
21 * Record declaration AST node type (added in JLS16 API).
22 *
23 * <pre>
24 * RecordDeclaration:
25 *     [ Javadoc ] { ExtendedModifier } <b>record</b> Identifier
26 *             [ <b>&lt;</b> TypeParameter <b>&gt;</b> ]
27 *             <b>(</b>
28 *              [ FormalParameter { <b>,</b> FormalParameter } ]
29 *            <b>)</b> { Dimension }
30 *             [ <b>implements</b> Type { <b>,</b> Type } ]
31 *             [ <b>;</b> { RecordBodyDeclaration | <b>;</b> } ]
32 * </pre>
33 * The {@link #bodyDeclarations()} list holds the class body declarations
34 * that appear after the semicolon.
35 * <p>
36 * When a Javadoc comment is present, the source
37 * range begins with the first character of the "/**" comment delimiter.
38 * When there is no Javadoc comment, the source range begins with the first
39 * character of the first modifier or annotation (if present), or the
40 * first character of the "record" keyword (if no
41 * modifiers or annotations). The source range extends through the last
42 * character of the "}" token following the body declarations.
43 * </p>
44 *
45 * @since 3.26
46 */
47@SuppressWarnings({ "rawtypes""unchecked" })
48public class RecordDeclaration extends AbstractTypeDeclaration {
49
50    /**
51     * The "javadoc" structural property of this node type (child type: {@link Javadoc}).
52     */
53    public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
54        internalJavadocPropertyFactory(RecordDeclaration.class);
55
56    /**
57     * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}).
58     */
59    public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
60        internalModifiers2PropertyFactory(RecordDeclaration.class);
61
62    /**
63     * The "name" structural property of this node type (child type: {@link SimpleName}).
64     */
65    public static final ChildPropertyDescriptor NAME_PROPERTY =
66        internalNamePropertyFactory(RecordDeclaration.class);
67
68
69    /**
70     * The "superInterfaceTypes" structural property of this node type (element type: {@link Type}).
71     */
72    public static final ChildListPropertyDescriptor SUPER_INTERFACE_TYPES_PROPERTY =
73        new ChildListPropertyDescriptor(RecordDeclaration.class"superInterfaceTypes"Type.classNO_CYCLE_RISK); //$NON-NLS-1$
74
75    /**
76     * The "typeParameters" structural property of this node type (element type: {@link TypeParameter}).
77     */
78    public static final ChildListPropertyDescriptor TYPE_PARAMETERS_PROPERTY =
79        new ChildListPropertyDescriptor(RecordDeclaration.class"typeParameters"TypeParameter.classNO_CYCLE_RISK); //$NON-NLS-1$
80
81    /**
82     * The "recordComponents" structural property of this node type (element type: {@link SingleVariableDeclaration}).
83     */
84    public static final ChildListPropertyDescriptor RECORD_COMPONENTS_PROPERTY =
85        new ChildListPropertyDescriptor(RecordDeclaration.class"recordComponents"SingleVariableDeclaration.classNO_CYCLE_RISK); //$NON-NLS-1$
86
87    /**
88     * The "bodyDeclarations" structural property of this node type (element type: {@link BodyDeclaration}).
89     */
90    public static final ChildListPropertyDescriptor BODY_DECLARATIONS_PROPERTY =
91        internalBodyDeclarationPropertyFactory(RecordDeclaration.class);
92
93
94    /**
95     * A character index into the original restricted identifier source string,
96     * or <code>-1</code> if no restricted identifier source position information is available
97     * for this node; <code>-1</code> by default.
98     */
99    private int restrictedIdentifierStartPosition = -1;
100
101    /**
102     * @param restrictedIdentifierStartPosition
103     * @since 3.26
104     */
105    public void setRestrictedIdentifierStartPosition(int restrictedIdentifierStartPosition) {
106        if (restrictedIdentifierStartPosition < 0) {
107            throw new IllegalArgumentException();
108        }
109        // restrictedIdentifierStartPosition is not considered a structural property
110        // but we protect it nevertheless
111        checkModifiable();
112        this.restrictedIdentifierStartPositionrestrictedIdentifierStartPosition;
113    }
114
115    /**
116     * @return restrictedIdentifierStartPosition
117     * @since 3.26
118     */
119    public int getRestrictedIdentifierStartPosition() {
120        return this.restrictedIdentifierStartPosition;
121    }
122
123    /**
124     * A list of property descriptors (element type:
125     * {@link StructuralPropertyDescriptor}),
126     * or null if uninitialized.
127     */
128    private static final List PROPERTY_DESCRIPTORS;
129
130    static {
131
132        ArrayList propertyList = new ArrayList(8);
133        createPropertyList(RecordDeclaration.classpropertyList);
134        addProperty(JAVADOC_PROPERTYpropertyList);
135        addProperty(MODIFIERS2_PROPERTYpropertyList);
136        addProperty(NAME_PROPERTYpropertyList);
137        addProperty(TYPE_PARAMETERS_PROPERTYpropertyList);
138        addProperty(RECORD_COMPONENTS_PROPERTYpropertyList);
139        addProperty(SUPER_INTERFACE_TYPES_PROPERTYpropertyList);
140        addProperty(BODY_DECLARATIONS_PROPERTYpropertyList);
141
142        PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
143    }
144
145    /**
146     * Returns a list of structural property descriptors for this node type.
147     * Clients must not modify the result.
148     *
149     * @param apiLevel the API level; one of the
150     * <code>AST.JLS*</code> constants
151
152     * @return a list of property descriptors (element type:
153     * {@link StructuralPropertyDescriptor})
154     * @since 3.26
155     */
156    public static List propertyDescriptors(int apiLevel) {
157        return PROPERTY_DESCRIPTORS;
158    }
159
160    /**
161     * The type parameters (element type: {@link TypeParameter}).
162     * defaults to an empty list
163     */
164    private ASTNode.NodeList typeParameters = new ASTNode.NodeList(TYPE_PARAMETERS_PROPERTY);
165
166
167    /**
168     * The superinterface types (element type: {@link Type}).
169     * defaults to an empty list
170     * (see constructor).
171     */
172    private ASTNode.NodeList superInterfaceTypes =  new ASTNode.NodeList(SUPER_INTERFACE_TYPES_PROPERTY);
173
174    /**
175     * The parameters (element type: {@link SingleVariableDeclaration}).
176     * defaults to an empty list
177     * (see constructor).
178     */
179    private ASTNode.NodeList recordComponents = new ASTNode.NodeList(RECORD_COMPONENTS_PROPERTY);
180
181
182    /**
183     * Creates a new AST node for a type declaration owned by the given
184     * AST. By default, the type declaration is for a class of an
185     * unspecified, but legal, name; no modifiers; no javadoc;
186     * no type parameters; no superinterfaces; and an empty list
187     * of body declarations.
188     * <p>
189     * N.B. This constructor is package-private; all subclasses must be
190     * declared in the same package; clients are unable to declare
191     * additional subclasses.
192     * </p>
193     *
194     * @param ast the AST that is to own this node
195     * @exception UnsupportedOperationException if this operation is used below JLS16
196     */
197    RecordDeclaration(AST ast) {
198        super(ast);
199        unsupportedBelow16();
200    }
201
202    @Override
203    final List internalStructuralPropertiesForType(int apiLevel) {
204        return propertyDescriptors(apiLevel);
205    }
206
207    @Override
208    final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor propertyboolean getASTNode child) {
209        if (property == JAVADOC_PROPERTY) {
210            if (get) {
211                return getJavadoc();
212            } else {
213                setJavadoc((Javadocchild);
214                return null;
215            }
216        }
217        if (property == NAME_PROPERTY) {
218            if (get) {
219                return getName();
220            } else {
221                setName((SimpleNamechild);
222                return null;
223            }
224        }
225        // allow default implementation to flag the error
226        return super.internalGetSetChildProperty(propertygetchild);
227    }
228
229    @Override
230    final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
231        if (property == MODIFIERS2_PROPERTY) {
232            return modifiers();
233        }
234        if (property == TYPE_PARAMETERS_PROPERTY) {
235            return typeParameters();
236        }
237        if (property == RECORD_COMPONENTS_PROPERTY) {
238            return recordComponents();
239        }
240        if (property == SUPER_INTERFACE_TYPES_PROPERTY) {
241            return superInterfaceTypes();
242        }
243        if (property == BODY_DECLARATIONS_PROPERTY) {
244            return bodyDeclarations();
245        }
246        // allow default implementation to flag the error
247        return super.internalGetChildListProperty(property);
248    }
249
250    @Override
251    final ChildPropertyDescriptor internalJavadocProperty() {
252        return JAVADOC_PROPERTY;
253    }
254
255    @Override
256    final ChildListPropertyDescriptor internalModifiers2Property() {
257        return MODIFIERS2_PROPERTY;
258    }
259
260    @Override
261    final ChildPropertyDescriptor internalNameProperty() {
262        return NAME_PROPERTY;
263    }
264
265    @Override
266    final ChildListPropertyDescriptor internalBodyDeclarationsProperty() {
267        return BODY_DECLARATIONS_PROPERTY;
268    }
269
270    @Override
271    final int getNodeType0() {
272        return RECORD_DECLARATION;
273    }
274
275    @Override
276    ASTNode clone0(AST target) {
277        RecordDeclaration result = new RecordDeclaration(target);
278        result.restrictedIdentifierStartPosition = getRestrictedIdentifierStartPosition();
279        result.setSourceRange(getStartPosition(), getLength());
280        result.setJavadoc(
281            (JavadocASTNode.copySubtree(targetgetJavadoc()));
282        result.setName((SimpleNamegetName().clone(target));
283        result.modifiers().addAll(ASTNode.copySubtrees(targetmodifiers()));
284        result.typeParameters().addAll(
285                ASTNode.copySubtrees(targettypeParameters()));
286        result.recordComponents().addAll(
287                ASTNode.copySubtrees(targetrecordComponents()));
288        result.superInterfaceTypes().addAll(
289                ASTNode.copySubtrees(targetsuperInterfaceTypes()));
290        result.bodyDeclarations().addAll(
291            ASTNode.copySubtrees(targetbodyDeclarations()));
292        return result;
293    }
294
295    @Override
296    final boolean subtreeMatch0(ASTMatcher matcherObject other) {
297        // dispatch to correct overloaded match method
298        return matcher.match(this, other);
299    }
300
301    @Override
302    void accept0(ASTVisitor visitor) {
303        boolean visitChildren = visitor.visit(this);
304        if (visitChildren) {
305            // visit children in normal left to right reading order
306            acceptChild(visitorgetJavadoc());
307            acceptChildren(visitor, this.modifiers);
308            acceptChild(visitorgetName());
309            acceptChildren(visitor, this.typeParameters);
310            acceptChildren(visitor, this.recordComponents);
311            acceptChildren(visitor, this.superInterfaceTypes);
312            acceptChildren(visitor, this.bodyDeclarations);
313        }
314        visitor.endVisit(this);
315    }
316
317    /**
318     * Returns the live ordered list of type parameters of this type
319     * declaration (added in JLS3 API). This list is non-empty for parameterized types.
320     *
321     * @return the live list of type parameters
322     *    (element type: {@link TypeParameter})
323     * @since 3.26
324     */
325    public List typeParameters() {
326        return this.typeParameters;
327    }
328
329
330    /**
331     * Returns the live ordered list of superinterfaces of this type
332     * declaration (added in JLS3 API). For a class declaration, these are the interfaces
333     * that this class implements; for an interface declaration,
334     * these are the interfaces that this interface extends.
335     *
336     * @return the live list of interface types
337     *    (element type: {@link Type})
338     * @since 3.26
339     */
340    public List superInterfaceTypes() {
341        return this.superInterfaceTypes;
342    }
343
344    /**
345     * Returns the live ordered list of recordComponents of record declaration.
346     *
347     * @return the live list of  recordComponents
348     *    (element type: {@link SingleVariableDeclaration})
349     * @since 3.26
350     */
351    public List recordComponents() {
352        return this.recordComponents;
353    }
354
355    /**
356     * Returns the ordered list of field declarations of this type
357     * declaration. For a class declaration, these are the
358     * field declarations; for an interface declaration, these are
359     * the constant declarations.
360     * <p>
361     * This convenience method returns this node's body declarations
362     * with non-fields filtered out. Unlike <code>bodyDeclarations</code>,
363     * this method does not return a live result.
364     * </p>
365     *
366     * @return the (possibly empty) list of field declarations
367     * @since 3.26
368     */
369    public FieldDeclaration[] getFields() {
370        List bd = bodyDeclarations();
371        int fieldCount = 0;
372        for (Iterator it = bd.listIterator(); it.hasNext(); ) {
373            if (it.next() instanceof FieldDeclaration) {
374                fieldCount++;
375            }
376        }
377        FieldDeclaration[] fields = new FieldDeclaration[fieldCount];
378        int next = 0;
379        for (Iterator it = bd.listIterator(); it.hasNext(); ) {
380            Object decl = it.next();
381            if (decl instanceof FieldDeclaration) {
382                fields[next++] = (FieldDeclarationdecl;
383            }
384        }
385        return fields;
386    }
387
388    /**
389     * Returns the ordered list of method declarations of this type
390     * declaration.
391     * <p>
392     * This convenience method returns this node's body declarations
393     * with non-methods filtered out. Unlike <code>bodyDeclarations</code>,
394     * this method does not return a live result.
395     * </p>
396     *
397     * @return the (possibly empty) list of method (and constructor)
398     *    declarations
399     * @since 3.26
400     */
401    public MethodDeclaration[] getMethods() {
402        List bd = bodyDeclarations();
403        int methodCount = 0;
404        for (Iterator it = bd.listIterator(); it.hasNext(); ) {
405            if (it.next() instanceof MethodDeclaration) {
406                methodCount++;
407            }
408        }
409        MethodDeclaration[] methods = new MethodDeclaration[methodCount];
410        int next = 0;
411        for (Iterator it = bd.listIterator(); it.hasNext(); ) {
412            Object decl = it.next();
413            if (decl instanceof MethodDeclaration) {
414                methods[next++] = (MethodDeclarationdecl;
415            }
416        }
417        return methods;
418    }
419
420    @Override
421    ITypeBinding internalResolveBinding() {
422        return this.ast.getBindingResolver().resolveType(this);
423    }
424
425    @Override
426    int memSize() {
427        return super.memSize() + 4 * 4;
428    }
429
430    @Override
431    int treeSize() {
432        return memSize()
433            + (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
434            + (this.modifiers == null ? 0 : this.modifiers.listSize())
435            + (this.typeName == null ? 0 : getName().treeSize())
436            + (this.typeParameters == null ? 0 : this.typeParameters.listSize())
437            + (this.superInterfaceTypes == null ? 0 : this.superInterfaceTypes.listSize())
438            + (this.recordComponents == null ? 0 : this.recordComponents.listSize())
439            + this.bodyDeclarations.listSize();
440    }
441
442    @Override
443    SimplePropertyDescriptor internalModifiersProperty() {
444        // node type does not exist before JLS 16
445        return null;
446    }
447
448}
449
450
MembersX
RecordDeclaration:internalGetSetChildProperty
RecordDeclaration:internalJavadocProperty
RecordDeclaration:internalNameProperty
RecordDeclaration:getRestrictedIdentifierStartPosition
RecordDeclaration:getMethods:Block:bd
RecordDeclaration:MODIFIERS2_PROPERTY
RecordDeclaration:recordComponents
RecordDeclaration:propertyDescriptors
RecordDeclaration:getMethods
RecordDeclaration:treeSize
RecordDeclaration:RECORD_COMPONENTS_PROPERTY
RecordDeclaration:NAME_PROPERTY
RecordDeclaration:superInterfaceTypes
RecordDeclaration:getFields:Block:Block:decl
RecordDeclaration:Block:propertyList
RecordDeclaration:subtreeMatch0
RecordDeclaration:JAVADOC_PROPERTY
RecordDeclaration:internalModifiers2Property
RecordDeclaration:internalModifiersProperty
RecordDeclaration:internalResolveBinding
RecordDeclaration:getFields
RecordDeclaration:getFields:Block:next
RecordDeclaration:restrictedIdentifierStartPosition
RecordDeclaration:setRestrictedIdentifierStartPosition
RecordDeclaration:BODY_DECLARATIONS_PROPERTY
RecordDeclaration:getMethods:Block:next
RecordDeclaration:accept0:Block:visitChildren
RecordDeclaration:internalGetChildListProperty
RecordDeclaration:getNodeType0
RecordDeclaration:RecordDeclaration
RecordDeclaration:internalStructuralPropertiesForType
RecordDeclaration:getMethods:Block:methods
RecordDeclaration:getMethods:Block:Block:decl
RecordDeclaration:typeParameters
RecordDeclaration:getFields:Block:bd
RecordDeclaration:getMethods:Block:methodCount
RecordDeclaration:PROPERTY_DESCRIPTORS
RecordDeclaration:SUPER_INTERFACE_TYPES_PROPERTY
RecordDeclaration:accept0
RecordDeclaration:getFields:Block:fieldCount
RecordDeclaration:getFields:Block:fields
RecordDeclaration:TYPE_PARAMETERS_PROPERTY
RecordDeclaration:clone0:Block:result
RecordDeclaration:internalBodyDeclarationsProperty
RecordDeclaration:clone0
RecordDeclaration:memSize
Members
X