1 /******************************************************************************* 2 * Copyright (c) 2000, 2020 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 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 15 package org.eclipse.jdt.core.dom; 16 17 import java.util.ArrayList; 18 import java.util.List; 19 20 import org.eclipse.jdt.internal.core.dom.util.DOMASTUtil; 21 22 /** 23 * Method declaration AST node type. A method declaration 24 * is the union of a method declaration and a constructor declaration. 25 * 26 * <pre> 27 * MethodDeclaration: 28 * [ Javadoc ] { ExtendedModifier } [ <b><</b> TypeParameter { <b>,</b> TypeParameter } <b>></b> ] ( Type | <b>void</b> ) 29 * Identifier <b>(</b> 30 * [ ReceiverParameter <b>,</b> ] [ FormalParameter { <b>,</b> FormalParameter } ] 31 * <b>)</b> { Dimension } 32 * [ <b>throws</b> Type { <b>,</b> Type } ] 33 * ( Block | <b>;</b> ) 34 * ConstructorDeclaration: 35 * [ Javadoc ] { ExtendedModifier } [ <b><</b> TypeParameter { <b>,</b> TypeParameter } <b>></b> ] 36 * Identifier <b>(</b> 37 * [ ReceiverParameter <b>,</b> ] [ FormalParameter { <b>,</b> FormalParameter } ] 38 * <b>)</b> { Dimension } 39 * [ <b>throws</b> Type { <b>,</b> Type } ] 40 * ( Block | <b>;</b> ) 41 * CompactConstructorDeclaration: 42 * [ Javadoc ] ExtendedModifier { ExtendedModifier} 43 * Identifier 44 * ( Block | <b>;</b> ) 45 * </pre> 46 * <p> 47 * The ReceiverParameter is represented as: <code>Type [ SimpleName <b>.</b> ] <b>this</b></code><br> 48 * The FormalParameter is represented by a {@link SingleVariableDeclaration}. 49 * </p> 50 * <p> 51 * When a Javadoc comment is present, the source 52 * range begins with the first character of the "/**" comment delimiter. 53 * When there is no Javadoc comment, the source range begins with the first 54 * character of the first modifier keyword (if modifiers), or the 55 * first character of the "<" token (method, no modifiers, type parameters), 56 * or the first character of the return type (method, no modifiers, no type 57 * parameters), or the first character of the identifier (constructor, 58 * no modifiers). The source range extends through the last character of the 59 * ";" token (if no body), or the last character of the block (if body). 60 * The compact constructor must be declared public. (jls-8.10.5) 61 * </p> 62 * 63 * @since 2.0 64 * @noinstantiate This class is not intended to be instantiated by clients. 65 */ 66 @SuppressWarnings({"rawtypes", "unchecked"}) 67 public class MethodDeclaration extends BodyDeclaration { 68 69 /** 70 * The "javadoc" structural property of this node type (child type: {@link Javadoc}). 71 * @since 3.0 72 */ 73 public static final ChildPropertyDescriptor JAVADOC_PROPERTY = 74 internalJavadocPropertyFactory(MethodDeclaration.class); 75 76 /** 77 * The "modifiers" structural property of this node type (type: {@link Integer}) (JLS2 API only). 78 * @since 3.0 79 * @deprecated In the JLS3 API, this property is replaced by {@link #MODIFIERS2_PROPERTY}. 80 */ 81 public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = 82 internalModifiersPropertyFactory(MethodDeclaration.class); 83 84 /** 85 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API). 86 * @since 3.1 87 */ 88 public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 89 internalModifiers2PropertyFactory(MethodDeclaration.class); 90 91 /** 92 * The "constructor" structural property of this node type (type: {@link Boolean}). 93 * @since 3.0 94 */ 95 public static final SimplePropertyDescriptor CONSTRUCTOR_PROPERTY = 96 new SimplePropertyDescriptor(MethodDeclaration.class, "constructor", boolean.class, MANDATORY); //$NON-NLS-1$ 97 98 /** 99 * The "compact constructor" structural property of record node type (type: {@link Boolean}). 100 * @since 3.22 101 */ 102 public static final SimplePropertyDescriptor COMPACT_CONSTRUCTOR_PROPERTY = 103 new SimplePropertyDescriptor(MethodDeclaration.class, "compactConstructor", boolean.class, OPTIONAL); //$NON-NLS-1$ 104 105 /** 106 * The "name" structural property of this node type (child type: {@link SimpleName}). 107 * @since 3.0 108 */ 109 public static final ChildPropertyDescriptor NAME_PROPERTY = 110 new ChildPropertyDescriptor(MethodDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$ 111 112 /** 113 * The "returnType" structural property of this node type (child type: {@link Type}) (JLS2 API only). 114 * @since 3.0 115 * @deprecated In the JLS3 API, this property is replaced by {@link #RETURN_TYPE2_PROPERTY}. 116 */ 117 public static final ChildPropertyDescriptor RETURN_TYPE_PROPERTY = 118 new ChildPropertyDescriptor(MethodDeclaration.class, "returnType", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$ 119 120 /** 121 * The "returnType2" structural property of this node type (child type: {@link Type}) (added in JLS3 API). 122 * @since 3.1 123 */ 124 public static final ChildPropertyDescriptor RETURN_TYPE2_PROPERTY = 125 new ChildPropertyDescriptor(MethodDeclaration.class, "returnType2", Type.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$ 126 127 /** 128 * The "extraDimensions" structural property of this node type (type: {@link Integer}) (below JLS8 only). 129 * 130 * @since 3.0 131 * @deprecated In JLS8 and later, use {@link MethodDeclaration#EXTRA_DIMENSIONS2_PROPERTY} instead. 132 */ 133 public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY = 134 new SimplePropertyDescriptor(MethodDeclaration.class, "extraDimensions", int.class, MANDATORY); //$NON-NLS-1$ 135 136 /** 137 * The "extraDimensions2" structural property of this node type (element type: {@link Dimension}) (added in JLS8 API). 138 * @since 3.10 139 */ 140 public static final ChildListPropertyDescriptor EXTRA_DIMENSIONS2_PROPERTY = 141 new ChildListPropertyDescriptor(MethodDeclaration.class, "extraDimensions2", Dimension.class, NO_CYCLE_RISK); //$NON-NLS-1$ 142 143 /** 144 * The "typeParameters" structural property of this node type (element type: {@link TypeParameter}) (added in JLS3 API). 145 * @since 3.1 146 */ 147 public static final ChildListPropertyDescriptor TYPE_PARAMETERS_PROPERTY = 148 new ChildListPropertyDescriptor(MethodDeclaration.class, "typeParameters", TypeParameter.class, NO_CYCLE_RISK); //$NON-NLS-1$ 149 150 /** 151 * The "parameters" structural property of this node type (element type: {@link SingleVariableDeclaration}). 152 * @since 3.0 153 */ 154 public static final ChildListPropertyDescriptor PARAMETERS_PROPERTY = 155 new ChildListPropertyDescriptor(MethodDeclaration.class, "parameters", SingleVariableDeclaration.class, CYCLE_RISK); //$NON-NLS-1$ 156 157 /** 158 * The "receiverType" structural property of this node type (child type: {@link Type}) (added in JLS8 API). 159 * @since 3.10 160 */ 161 public static final ChildPropertyDescriptor RECEIVER_TYPE_PROPERTY = 162 new ChildPropertyDescriptor(MethodDeclaration.class, "receiverType", Type.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$ 163 164 /** 165 * The "receiverQualifier" structural property of this node type (child type: {@link SimpleName}) (added in JLS8 API). 166 * @since 3.10 167 */ 168 public static final ChildPropertyDescriptor RECEIVER_QUALIFIER_PROPERTY = 169 new ChildPropertyDescriptor(MethodDeclaration.class, "receiverQualifier", SimpleName.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$ 170 171 /** 172 * The "thrownExceptions" structural property of this node type (element type: {@link Name}) (before JLS8 only). 173 * @deprecated In JLS8 and later, use {@link MethodDeclaration#THROWN_EXCEPTION_TYPES_PROPERTY} instead. 174 * @since 3.0 175 */ 176 public static final ChildListPropertyDescriptor THROWN_EXCEPTIONS_PROPERTY = 177 new ChildListPropertyDescriptor(MethodDeclaration.class, "thrownExceptions", Name.class, NO_CYCLE_RISK); //$NON-NLS-1$ 178 179 /** 180 * The "thrownExceptionTypes" structural property of this node type (element type: {@link Type}) (added in JLS8 API). 181 * @since 3.10 182 */ 183 public static final ChildListPropertyDescriptor THROWN_EXCEPTION_TYPES_PROPERTY = 184 new ChildListPropertyDescriptor(MethodDeclaration.class, "thrownExceptionTypes", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$ 185 186 /** 187 * The "body" structural property of this node type (child type: {@link Block}). 188 * @since 3.0 189 */ 190 public static final ChildPropertyDescriptor BODY_PROPERTY = 191 new ChildPropertyDescriptor(MethodDeclaration.class, "body", Block.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$ 192 193 /** 194 * A list of property descriptors (element type: 195 * {@link StructuralPropertyDescriptor}), 196 * or null if uninitialized. 197 * @since 3.0 198 */ 199 private static final List PROPERTY_DESCRIPTORS_2_0; 200 201 /** 202 * A list of property descriptors (element type: 203 * {@link StructuralPropertyDescriptor}), 204 * or null if uninitialized. 205 * @since 3.1 206 */ 207 private static final List PROPERTY_DESCRIPTORS_3_0; 208 209 /** 210 * A list of property descriptors (element type: 211 * {@link StructuralPropertyDescriptor}), 212 * or null if uninitialized. 213 * @since 3.10 214 */ 215 private static final List PROPERTY_DESCRIPTORS_8_0; 216 217 /** 218 * A list of property descriptors (element type: 219 * {@link StructuralPropertyDescriptor}), 220 * or null if uninitialized. 221 * @since 3.22 222 */ 223 private static final List PROPERTY_DESCRIPTORS_9_0; 224 225 static { 226 List propertyList = new ArrayList(10); createPropertyList(MethodDeclaration.class, propertyList)227 createPropertyList(MethodDeclaration.class, propertyList); addProperty(JAVADOC_PROPERTY, propertyList)228 addProperty(JAVADOC_PROPERTY, propertyList); addProperty(MODIFIERS_PROPERTY, propertyList)229 addProperty(MODIFIERS_PROPERTY, propertyList); addProperty(CONSTRUCTOR_PROPERTY, propertyList)230 addProperty(CONSTRUCTOR_PROPERTY, propertyList); addProperty(RETURN_TYPE_PROPERTY, propertyList)231 addProperty(RETURN_TYPE_PROPERTY, propertyList); addProperty(NAME_PROPERTY, propertyList)232 addProperty(NAME_PROPERTY, propertyList); addProperty(PARAMETERS_PROPERTY, propertyList)233 addProperty(PARAMETERS_PROPERTY, propertyList); addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList)234 addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList); addProperty(THROWN_EXCEPTIONS_PROPERTY, propertyList)235 addProperty(THROWN_EXCEPTIONS_PROPERTY, propertyList); addProperty(BODY_PROPERTY, propertyList)236 addProperty(BODY_PROPERTY, propertyList); 237 PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList); 238 239 propertyList = new ArrayList(11); createPropertyList(MethodDeclaration.class, propertyList)240 createPropertyList(MethodDeclaration.class, propertyList); addProperty(JAVADOC_PROPERTY, propertyList)241 addProperty(JAVADOC_PROPERTY, propertyList); addProperty(MODIFIERS2_PROPERTY, propertyList)242 addProperty(MODIFIERS2_PROPERTY, propertyList); addProperty(CONSTRUCTOR_PROPERTY, propertyList)243 addProperty(CONSTRUCTOR_PROPERTY, propertyList); addProperty(TYPE_PARAMETERS_PROPERTY, propertyList)244 addProperty(TYPE_PARAMETERS_PROPERTY, propertyList); addProperty(RETURN_TYPE2_PROPERTY, propertyList)245 addProperty(RETURN_TYPE2_PROPERTY, propertyList); addProperty(NAME_PROPERTY, propertyList)246 addProperty(NAME_PROPERTY, propertyList); addProperty(PARAMETERS_PROPERTY, propertyList)247 addProperty(PARAMETERS_PROPERTY, propertyList); addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList)248 addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList); addProperty(THROWN_EXCEPTIONS_PROPERTY, propertyList)249 addProperty(THROWN_EXCEPTIONS_PROPERTY, propertyList); addProperty(BODY_PROPERTY, propertyList)250 addProperty(BODY_PROPERTY, propertyList); 251 PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList); 252 253 propertyList = new ArrayList(13); createPropertyList(MethodDeclaration.class, propertyList)254 createPropertyList(MethodDeclaration.class, propertyList); addProperty(JAVADOC_PROPERTY, propertyList)255 addProperty(JAVADOC_PROPERTY, propertyList); addProperty(MODIFIERS2_PROPERTY, propertyList)256 addProperty(MODIFIERS2_PROPERTY, propertyList); addProperty(CONSTRUCTOR_PROPERTY, propertyList)257 addProperty(CONSTRUCTOR_PROPERTY, propertyList); addProperty(TYPE_PARAMETERS_PROPERTY, propertyList)258 addProperty(TYPE_PARAMETERS_PROPERTY, propertyList); addProperty(RETURN_TYPE2_PROPERTY, propertyList)259 addProperty(RETURN_TYPE2_PROPERTY, propertyList); addProperty(NAME_PROPERTY, propertyList)260 addProperty(NAME_PROPERTY, propertyList); addProperty(RECEIVER_TYPE_PROPERTY, propertyList)261 addProperty(RECEIVER_TYPE_PROPERTY, propertyList); addProperty(RECEIVER_QUALIFIER_PROPERTY, propertyList)262 addProperty(RECEIVER_QUALIFIER_PROPERTY, propertyList); addProperty(PARAMETERS_PROPERTY, propertyList)263 addProperty(PARAMETERS_PROPERTY, propertyList); addProperty(EXTRA_DIMENSIONS2_PROPERTY, propertyList)264 addProperty(EXTRA_DIMENSIONS2_PROPERTY, propertyList); addProperty(THROWN_EXCEPTION_TYPES_PROPERTY, propertyList)265 addProperty(THROWN_EXCEPTION_TYPES_PROPERTY, propertyList); addProperty(BODY_PROPERTY, propertyList)266 addProperty(BODY_PROPERTY, propertyList); 267 PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList); 268 269 propertyList = new ArrayList(14); createPropertyList(MethodDeclaration.class, propertyList)270 createPropertyList(MethodDeclaration.class, propertyList); addProperty(JAVADOC_PROPERTY, propertyList)271 addProperty(JAVADOC_PROPERTY, propertyList); addProperty(MODIFIERS2_PROPERTY, propertyList)272 addProperty(MODIFIERS2_PROPERTY, propertyList); addProperty(CONSTRUCTOR_PROPERTY, propertyList)273 addProperty(CONSTRUCTOR_PROPERTY, propertyList); addProperty(TYPE_PARAMETERS_PROPERTY, propertyList)274 addProperty(TYPE_PARAMETERS_PROPERTY, propertyList); addProperty(RETURN_TYPE2_PROPERTY, propertyList)275 addProperty(RETURN_TYPE2_PROPERTY, propertyList); addProperty(NAME_PROPERTY, propertyList)276 addProperty(NAME_PROPERTY, propertyList); addProperty(RECEIVER_TYPE_PROPERTY, propertyList)277 addProperty(RECEIVER_TYPE_PROPERTY, propertyList); addProperty(RECEIVER_QUALIFIER_PROPERTY, propertyList)278 addProperty(RECEIVER_QUALIFIER_PROPERTY, propertyList); addProperty(PARAMETERS_PROPERTY, propertyList)279 addProperty(PARAMETERS_PROPERTY, propertyList); addProperty(EXTRA_DIMENSIONS2_PROPERTY, propertyList)280 addProperty(EXTRA_DIMENSIONS2_PROPERTY, propertyList); addProperty(THROWN_EXCEPTION_TYPES_PROPERTY, propertyList)281 addProperty(THROWN_EXCEPTION_TYPES_PROPERTY, propertyList); addProperty(BODY_PROPERTY, propertyList)282 addProperty(BODY_PROPERTY, propertyList); addProperty(COMPACT_CONSTRUCTOR_PROPERTY, propertyList)283 addProperty(COMPACT_CONSTRUCTOR_PROPERTY, propertyList); 284 PROPERTY_DESCRIPTORS_9_0 = reapPropertyList(propertyList); 285 } 286 287 /** 288 * Returns a list of structural property descriptors for this node type. 289 * Clients must not modify the result. 290 * 291 * @param apiLevel the API level; one of the AST.JLS* constants 292 * @return a list of property descriptors (element type: 293 * {@link StructuralPropertyDescriptor}) 294 * @since 3.0 295 */ propertyDescriptors(int apiLevel)296 public static List propertyDescriptors(int apiLevel) { 297 return propertyDescriptors(apiLevel, false); 298 } 299 300 /** 301 * Returns a list of structural property descriptors for this node type. 302 * Clients must not modify the result. 303 * 304 * @param apiLevel the API level; one of the 305 * <code>AST.JLS*</code> constants 306 * @param previewEnabled the previewEnabled flag 307 * @return a list of property descriptors (element type: 308 * {@link StructuralPropertyDescriptor}) 309 * @noreference This method is not intended to be referenced by clients. 310 * @since 3.22 311 */ propertyDescriptors(int apiLevel, boolean previewEnabled)312 public static List propertyDescriptors(int apiLevel, boolean previewEnabled) { 313 if (apiLevel == AST.JLS2_INTERNAL) { 314 return PROPERTY_DESCRIPTORS_2_0; 315 } else if (apiLevel < AST.JLS8_INTERNAL) { 316 return PROPERTY_DESCRIPTORS_3_0; 317 } else if (DOMASTUtil.isRecordDeclarationSupported(apiLevel, previewEnabled)) { 318 return PROPERTY_DESCRIPTORS_9_0; 319 } else { 320 return PROPERTY_DESCRIPTORS_8_0; 321 } 322 } 323 324 /** 325 * <code>true</code> for a constructor, <code>false</code> for a method. 326 * Defaults to method. 327 */ 328 private boolean isConstructor = false; 329 330 331 /** 332 * <code>true</code> for a compact constructor in a record, <code>false</code> for a method. 333 * Defaults to method. 334 */ 335 private boolean isCompactConstructor = false; 336 337 /** 338 * The method name; lazily initialized; defaults to an unspecified, 339 * legal Java identifier. 340 */ 341 private SimpleName methodName = null; 342 343 /** 344 * The explicit receiver type, or <code>null</code> if none. 345 * Defaults to none. 346 * @since 3.10 347 */ 348 private Type optionalReceiverType = null; 349 350 /** 351 * Qualifying name of the explicit </code>this</code> parameter, or <code>null</code> if none. 352 * Defaults to none. 353 * @since 3.10 354 */ 355 private SimpleName optionalReceiverQualifier = null; 356 357 /** 358 * The parameter declarations 359 * (element type: {@link SingleVariableDeclaration}). 360 * Defaults to an empty list. 361 */ 362 private ASTNode.NodeList parameters = 363 new ASTNode.NodeList(PARAMETERS_PROPERTY); 364 365 /** 366 * The return type. 367 * JLS2 behavior: lazily initialized; defaults to void. 368 * JLS3 and later: lazily initialized; defaults to void; null allowed. 369 * Note that this field is ignored for constructor declarations. 370 */ 371 private Type returnType = null; 372 373 /** 374 * Indicated whether the return type has been initialized. 375 * @since 3.1 376 */ 377 private boolean returnType2Initialized = false; 378 379 /** 380 * The type paramters (element type: {@link TypeParameter}). 381 * Null in JLS2. Added in JLS3; defaults to an empty list 382 * (see constructor). 383 * @since 3.1 384 */ 385 private ASTNode.NodeList typeParameters = null; 386 387 /** 388 * The number of array dimensions that appear after the parameters, rather 389 * than after the return type itself; defaults to 0. Not used in JLS8 and later. 390 * 391 * @since 2.1 392 * @deprecated In JLS8 and later, use {@link #extraDimensions} instead. 393 */ 394 private int extraArrayDimensions = 0; 395 396 /** 397 * List of extra dimensions this node has with optional annotations 398 * (element type: {@link Dimension}). 399 * Null before JLS8. Added in JLS8; defaults to an empty list 400 * (see constructor). 401 * 402 * @since 3.10 403 */ 404 private ASTNode.NodeList extraDimensions = null; 405 406 /** 407 * The list of thrown exception names (element type: {@link Name}). 408 * Before JLS8: defaults to an empty list (see constructor). 409 * JLS8 and later: null. 410 * @deprecated In JLS8 and later, use {@link #thrownExceptionTypes} instead. 411 */ 412 private ASTNode.NodeList thrownExceptions = null; 413 414 /** 415 * The list of thrown exception Types (element type: {@link Type}). 416 * Null before JLS8. Added in JLS8; defaults to an empty list 417 * (see constructor). 418 * 419 * @since 3.10 420 */ 421 private ASTNode.NodeList thrownExceptionTypes = null; 422 423 /** 424 * The method body, or <code>null</code> if none. 425 * Defaults to none. 426 */ 427 private Block optionalBody = null; 428 429 /** 430 * Creates a new AST node for a method declaration owned 431 * by the given AST. By default, the declaration is for a method of an 432 * unspecified, but legal, name; no modifiers; no javadoc; no type 433 * parameters; void return type; no parameters; no array dimensions after 434 * the parameters; no thrown exceptions; and no body (as opposed to an 435 * empty body). 436 * <p> 437 * N.B. This constructor is package-private; all subclasses must be 438 * declared in the same package; clients are unable to declare 439 * additional subclasses. 440 * </p> 441 * 442 * @param ast the AST that is to own this node 443 */ MethodDeclaration(AST ast)444 MethodDeclaration(AST ast) { 445 super(ast); 446 if (ast.apiLevel >= AST.JLS3_INTERNAL) { 447 this.typeParameters = new ASTNode.NodeList(TYPE_PARAMETERS_PROPERTY); 448 } 449 if (ast.apiLevel < AST.JLS8_INTERNAL) { 450 this.thrownExceptions = new ASTNode.NodeList(THROWN_EXCEPTIONS_PROPERTY); 451 } else { 452 this.extraDimensions = new ASTNode.NodeList(EXTRA_DIMENSIONS2_PROPERTY); 453 this.thrownExceptionTypes = new ASTNode.NodeList(THROWN_EXCEPTION_TYPES_PROPERTY); 454 } 455 } 456 457 /* (omit javadoc for this method) 458 * Method declared on ASTNode. 459 * @since 3.0 460 */ 461 @Override internalStructuralPropertiesForType(int apiLevel)462 final List internalStructuralPropertiesForType(int apiLevel) { 463 return propertyDescriptors(apiLevel); 464 } 465 466 @Override internalStructuralPropertiesForType(int apiLevel, boolean previewEnabled)467 final List internalStructuralPropertiesForType(int apiLevel, boolean previewEnabled) { 468 return propertyDescriptors(apiLevel, previewEnabled); 469 } 470 471 @Override internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value)472 final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) { 473 if (property == MODIFIERS_PROPERTY) { 474 if (get) { 475 return getModifiers(); 476 } else { 477 internalSetModifiers(value); 478 return 0; 479 } 480 } 481 if (property == EXTRA_DIMENSIONS_PROPERTY) { 482 if (get) { 483 return getExtraDimensions(); 484 } else { 485 setExtraDimensions(value); 486 return 0; 487 } 488 } 489 // allow default implementation to flag the error 490 return super.internalGetSetIntProperty(property, get, value); 491 } 492 493 @Override internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value)494 final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) { 495 if (property == CONSTRUCTOR_PROPERTY) { 496 if (get) { 497 return isConstructor(); 498 } else { 499 setConstructor(value); 500 return false; 501 } 502 } else if (property == COMPACT_CONSTRUCTOR_PROPERTY) { 503 if (get) { 504 return isCompactConstructor(); 505 } else { 506 setCompactConstructor(value); 507 return false; 508 } 509 } 510 // allow default implementation to flag the error 511 return super.internalGetSetBooleanProperty(property, get, value); 512 } 513 514 515 516 @Override internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child)517 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) { 518 if (property == JAVADOC_PROPERTY) { 519 if (get) { 520 return getJavadoc(); 521 } else { 522 setJavadoc((Javadoc) child); 523 return null; 524 } 525 } 526 if (property == NAME_PROPERTY) { 527 if (get) { 528 return getName(); 529 } else { 530 setName((SimpleName) child); 531 return null; 532 } 533 } 534 if (property == RETURN_TYPE_PROPERTY) { 535 if (get) { 536 return getReturnType(); 537 } else { 538 setReturnType((Type) child); 539 return null; 540 } 541 } 542 if (property == RETURN_TYPE2_PROPERTY) { 543 if (get) { 544 return getReturnType2(); 545 } else { 546 setReturnType2((Type) child); 547 return null; 548 } 549 } 550 if (property == RECEIVER_TYPE_PROPERTY) { 551 if (get) { 552 return getReceiverType(); 553 } else { 554 setReceiverType((Type) child); 555 return null; 556 } 557 } 558 if (property == RECEIVER_QUALIFIER_PROPERTY) { 559 if (get) { 560 return getReceiverQualifier(); 561 } else { 562 setReceiverQualifier((SimpleName) child); 563 return null; 564 } 565 } 566 if (property == BODY_PROPERTY) { 567 if (get) { 568 return getBody(); 569 } else { 570 setBody((Block) child); 571 return null; 572 } 573 } 574 // allow default implementation to flag the error 575 return super.internalGetSetChildProperty(property, get, child); 576 } 577 578 @Override internalGetChildListProperty(ChildListPropertyDescriptor property)579 final List internalGetChildListProperty(ChildListPropertyDescriptor property) { 580 if (property == MODIFIERS2_PROPERTY) { 581 return modifiers(); 582 } 583 if (property == TYPE_PARAMETERS_PROPERTY) { 584 return typeParameters(); 585 } 586 if (property == PARAMETERS_PROPERTY) { 587 return parameters(); 588 } 589 if (property == THROWN_EXCEPTIONS_PROPERTY) { 590 return thrownExceptions(); 591 } 592 if (property == THROWN_EXCEPTION_TYPES_PROPERTY) { 593 return thrownExceptionTypes(); 594 } 595 if (property == EXTRA_DIMENSIONS2_PROPERTY) { 596 return extraDimensions(); 597 } 598 // allow default implementation to flag the error 599 return super.internalGetChildListProperty(property); 600 } 601 602 @Override internalJavadocProperty()603 final ChildPropertyDescriptor internalJavadocProperty() { 604 return JAVADOC_PROPERTY; 605 } 606 607 @Override internalModifiers2Property()608 final ChildListPropertyDescriptor internalModifiers2Property() { 609 return MODIFIERS2_PROPERTY; 610 } 611 612 @Override internalModifiersProperty()613 final SimplePropertyDescriptor internalModifiersProperty() { 614 return MODIFIERS_PROPERTY; 615 } 616 617 @Override getNodeType0()618 final int getNodeType0() { 619 return METHOD_DECLARATION; 620 } 621 622 @Override clone0(AST target)623 ASTNode clone0(AST target) { 624 MethodDeclaration result = new MethodDeclaration(target); 625 result.setSourceRange(getStartPosition(), getLength()); 626 result.setJavadoc( 627 (Javadoc) ASTNode.copySubtree(target, getJavadoc())); 628 if (this.ast.apiLevel == AST.JLS2_INTERNAL) { 629 result.internalSetModifiers(getModifiers()); 630 result.setReturnType( 631 (Type) ASTNode.copySubtree(target, getReturnType())); 632 } 633 if (this.ast.apiLevel >= AST.JLS3_INTERNAL) { 634 result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers())); 635 result.typeParameters().addAll( 636 ASTNode.copySubtrees(target, typeParameters())); 637 result.setReturnType2( 638 (Type) ASTNode.copySubtree(target, getReturnType2())); 639 } 640 result.setConstructor(isConstructor()); 641 result.setName((SimpleName) getName().clone(target)); 642 if (this.ast.apiLevel >= AST.JLS8_INTERNAL) { 643 result.setReceiverType((Type) ASTNode.copySubtree(target, getReceiverType())); 644 result.setReceiverQualifier((SimpleName) ASTNode.copySubtree(target, getReceiverQualifier())); 645 } 646 result.parameters().addAll( 647 ASTNode.copySubtrees(target, parameters())); 648 if (this.ast.apiLevel >= AST.JLS8_INTERNAL) { 649 result.extraDimensions().addAll(ASTNode.copySubtrees(target, extraDimensions())); 650 } else { 651 result.setExtraDimensions(getExtraDimensions()); 652 } 653 if (this.ast.apiLevel() >= AST.JLS8_INTERNAL) { 654 result.thrownExceptionTypes().addAll(ASTNode.copySubtrees(target, thrownExceptionTypes())); 655 } else { 656 result.thrownExceptions().addAll(ASTNode.copySubtrees(target, thrownExceptions())); 657 } 658 if (DOMASTUtil.isRecordDeclarationSupported(this.ast)) { 659 result.setCompactConstructor(isCompactConstructor()); 660 } 661 result.setBody( 662 (Block) ASTNode.copySubtree(target, getBody())); 663 return result; 664 } 665 666 @Override subtreeMatch0(ASTMatcher matcher, Object other)667 final boolean subtreeMatch0(ASTMatcher matcher, Object other) { 668 // dispatch to correct overloaded match method 669 return matcher.match(this, other); 670 } 671 672 @Override accept0(ASTVisitor visitor)673 void accept0(ASTVisitor visitor) { 674 boolean visitChildren = visitor.visit(this); 675 if (visitChildren) { 676 // visit children in normal left to right reading order 677 acceptChild(visitor, getJavadoc()); 678 if (this.ast.apiLevel == AST.JLS2_INTERNAL) { 679 acceptChild(visitor, getReturnType()); 680 } else { 681 acceptChildren(visitor, this.modifiers); 682 acceptChildren(visitor, this.typeParameters); 683 acceptChild(visitor, getReturnType2()); 684 } 685 // n.b. visit return type even for constructors 686 acceptChild(visitor, getName()); 687 if (this.ast.apiLevel >= AST.JLS8_INTERNAL) { 688 acceptChild(visitor, this.optionalReceiverType); 689 acceptChild(visitor, this.optionalReceiverQualifier); 690 } 691 acceptChildren(visitor, this.parameters); 692 if (this.ast.apiLevel() >= AST.JLS8_INTERNAL) { 693 acceptChildren(visitor, this.extraDimensions); 694 acceptChildren(visitor, this.thrownExceptionTypes); 695 } else { 696 acceptChildren(visitor, this.thrownExceptions); 697 } 698 acceptChild(visitor, getBody()); 699 } 700 visitor.endVisit(this); 701 } 702 703 /** 704 * Returns whether this declaration declares a constructor or a method. 705 * 706 * @return <code>true</code> if this is a constructor declaration, 707 * and <code>false</code> if this is a method declaration 708 */ isConstructor()709 public boolean isConstructor() { 710 return this.isConstructor; 711 } 712 713 /** 714 * Sets whether this declaration declares a constructor or a method. 715 * 716 * @param isConstructor <code>true</code> for a constructor declaration, 717 * and <code>false</code> for a method declaration 718 */ setConstructor(boolean isConstructor)719 public void setConstructor(boolean isConstructor) { 720 preValueChange(CONSTRUCTOR_PROPERTY); 721 this.isConstructor = isConstructor; 722 postValueChange(CONSTRUCTOR_PROPERTY); 723 } 724 725 /** 726 * Returns whether this declaration declares a constructor or a method. 727 * 728 * @return <code>true</code> if this is a compact constructor declaration in a record, 729 * and <code>false</code> if this is a method declaration 730 * @since 3.22 731 * @noreference This method is not intended to be referenced by clients. 732 * @exception UnsupportedOperationException if this operation is not used in JLS14 733 * @exception UnsupportedOperationException if this operation is used with previewEnabled flag as false 734 */ 735 isCompactConstructor()736 public boolean isCompactConstructor() { 737 supportedOnlyIn14(); 738 unsupportedWithoutPreviewError(); 739 return this.isCompactConstructor; 740 } 741 742 /** 743 * Sets whether this declaration declares a compact constructor in a record or a method. 744 * 745 * @param isCompactConstructor <code>true</code> for a constructor declaration, 746 * and <code>false</code> for a method declaration 747 * @since 3.22 748 * @noreference This method is not intended to be referenced by clients. 749 * @exception UnsupportedOperationException if this operation is not used in JLS14 750 * @exception UnsupportedOperationException if this operation is used with previewEnabled flag as false 751 */ 752 setCompactConstructor(boolean isCompactConstructor)753 public void setCompactConstructor(boolean isCompactConstructor) { 754 preValueChange(COMPACT_CONSTRUCTOR_PROPERTY); 755 this.isCompactConstructor = isCompactConstructor; 756 postValueChange(COMPACT_CONSTRUCTOR_PROPERTY); 757 } 758 759 /** 760 * Returns the live ordered list of type parameters of this method 761 * declaration (added in JLS3 API). This list is non-empty for parameterized methods. 762 * 763 * @return the live list of type parameters 764 * (element type: {@link TypeParameter}) 765 * @exception UnsupportedOperationException if this operation is used in 766 * a JLS2 AST 767 * @since 3.1 768 */ typeParameters()769 public List typeParameters() { 770 // more efficient than just calling unsupportedIn2() to check 771 if (this.typeParameters == null) { 772 unsupportedIn2(); 773 } 774 return this.typeParameters; 775 } 776 777 /** 778 * Returns the name of the method declared in this method declaration. 779 * For a constructor declaration, this should be the same as the name 780 * of the class. 781 * 782 * @return the method name node 783 */ getName()784 public SimpleName getName() { 785 if (this.methodName == null) { 786 // lazy init must be thread-safe for readers 787 synchronized (this) { 788 if (this.methodName == null) { 789 preLazyInit(); 790 this.methodName = new SimpleName(this.ast); 791 postLazyInit(this.methodName, NAME_PROPERTY); 792 } 793 } 794 } 795 return this.methodName; 796 } 797 798 /** 799 * Sets the name of the method declared in this method declaration to the 800 * given name. For a constructor declaration, this should be the same as 801 * the name of the class. 802 * 803 * @param methodName the new method name 804 * @exception IllegalArgumentException if: 805 * <ul> 806 * <li>the node belongs to a different AST</li> 807 * <li>the node already has a parent</li> 808 * </ul> 809 */ setName(SimpleName methodName)810 public void setName(SimpleName methodName) { 811 if (methodName == null) { 812 throw new IllegalArgumentException(); 813 } 814 ASTNode oldChild = this.methodName; 815 preReplaceChild(oldChild, methodName, NAME_PROPERTY); 816 this.methodName = methodName; 817 postReplaceChild(oldChild, methodName, NAME_PROPERTY); 818 } 819 820 /** 821 * Returns the receiver type explicitly declared in the method or constructor 822 * declaration (added in JLS8 API). 823 * 824 * If the receiver is not explicitly declared in the method or constructor 825 * declaration, <code>null</code> is returned. 826 * 827 * @return the receiver type or <code>null</code> if receiver is not declared explicitly 828 * @exception UnsupportedOperationException if this operation is used below JLS8 829 * @since 3.10 830 */ getReceiverType()831 public Type getReceiverType() { 832 unsupportedIn2_3_4(); 833 return this.optionalReceiverType; 834 } 835 836 /** 837 * Sets or clears the given type as the type of explicit receiver parameter (added in JLS8 API). 838 * <p> 839 * A receiver type is only legal in Java code if it appears on an instance method or on a constructor of an inner class. 840 * </p> 841 * 842 * @param receiverType type of the explicit receiver parameter, or <code>null</code> if there is none 843 * @exception UnsupportedOperationException if this operation is used below JLS8 844 * @since 3.10 845 */ setReceiverType(Type receiverType)846 public void setReceiverType(Type receiverType) { 847 unsupportedIn2_3_4(); 848 ASTNode oldChild = this.optionalReceiverType; 849 preReplaceChild(oldChild, receiverType, RECEIVER_TYPE_PROPERTY); 850 this.optionalReceiverType = receiverType; 851 postReplaceChild(oldChild, receiverType, RECEIVER_TYPE_PROPERTY); 852 } 853 854 /** 855 * Returns the qualifying name, if any, for the explicit receiver or <code>null</code> if not used (added in JLS8 API). 856 * <p> 857 * A receiver qualifier is only legal in Java code if it appears on a constructor of an inner class. 858 * </p> 859 * 860 * @return the qualifying name or <code>null</code> if a qualifier was not specified 861 * @exception UnsupportedOperationException if this operation is used below JLS8 862 * @since 3.10 863 */ getReceiverQualifier()864 public SimpleName getReceiverQualifier() { 865 unsupportedIn2_3_4(); 866 return this.optionalReceiverQualifier; 867 } 868 869 /** 870 * Sets the given simple name as the qualifier for the receiver (added in JLS8 API). 871 * 872 * @param receiverQualifier explicit receiver parameter to be added to the method declaration 873 * @exception UnsupportedOperationException if this operation is used below JLS8 874 * @since 3.10 875 */ setReceiverQualifier(SimpleName receiverQualifier)876 public void setReceiverQualifier(SimpleName receiverQualifier) { 877 unsupportedIn2_3_4(); 878 ASTNode oldChild = this.optionalReceiverQualifier; 879 preReplaceChild(oldChild, receiverQualifier, RECEIVER_QUALIFIER_PROPERTY); 880 this.optionalReceiverQualifier = receiverQualifier; 881 postReplaceChild(oldChild, receiverQualifier, RECEIVER_QUALIFIER_PROPERTY); 882 } 883 884 /** 885 * Returns the live ordered list of method parameter declarations for this 886 * method declaration. 887 * 888 * @return the live list of method parameter declarations 889 * (element type: {@link SingleVariableDeclaration}) 890 */ parameters()891 public List parameters() { 892 return this.parameters; 893 } 894 895 /** 896 * Returns whether this method declaration declares a 897 * variable arity method (added in JLS3 API). The convenience method checks 898 * whether the last parameter is so marked. 899 * 900 * @return <code>true</code> if this is a variable arity method declaration, 901 * and <code>false</code> otherwise 902 * @exception UnsupportedOperationException if this operation is used in 903 * a JLS2 AST 904 * @see SingleVariableDeclaration#isVarargs() 905 * @since 3.1 906 */ isVarargs()907 public boolean isVarargs() { 908 // more efficient than just calling unsupportedIn2() to check 909 if (this.modifiers == null) { 910 unsupportedIn2(); 911 } 912 if (parameters().isEmpty()) { 913 return false; 914 } else { 915 SingleVariableDeclaration v = (SingleVariableDeclaration) parameters().get(parameters().size() - 1); 916 return v.isVarargs(); 917 } 918 } 919 920 /** 921 * Returns the live ordered list of thrown exception names in this method 922 * declaration (below JLS8 API only). 923 * 924 * @return the live list of exception names 925 * (element type: {@link Name}) 926 * @exception UnsupportedOperationException if this operation is used in 927 * a JLS8 or later AST 928 * @deprecated In the JLS8 API, this method is replaced by {@link #thrownExceptionTypes()}. 929 */ thrownExceptions()930 public List thrownExceptions() { 931 return internalThrownExceptions(); 932 } 933 934 /** 935 * Internal synonym for deprecated method. Used to avoid 936 * deprecation warnings. 937 * @exception UnsupportedOperationException if this operation is used in 938 * a JLS8 or later AST 939 * @since 3.10 940 */ internalThrownExceptions()941 /*package*/ List internalThrownExceptions() { 942 // more efficient than just calling supportedOnlyIn2_3_4() to check 943 if (this.thrownExceptions == null) { 944 supportedOnlyIn2_3_4(); 945 } 946 return this.thrownExceptions; 947 } 948 949 /** 950 * Returns the live ordered list of thrown exception types in this method 951 * declaration. 952 * 953 * @return the live list of exception types 954 * (element type: {@link Type}) 955 * @exception UnsupportedOperationException if this operation is used 956 * in a JLS2, JLS3 or JLS4 AST 957 * @since 3.10 958 */ thrownExceptionTypes()959 public List thrownExceptionTypes() { 960 if (this.thrownExceptionTypes == null) { 961 unsupportedIn2_3_4(); 962 } 963 return this.thrownExceptionTypes; 964 } 965 966 /** 967 * Returns the return type of the method declared in this method 968 * declaration, exclusive of any extra array dimensions (JLS2 API only). 969 * This is one of the few places where the void type is meaningful. 970 * <p> 971 * Note that this child is not relevant for constructor declarations 972 * (although, it does still figure in subtree equality comparisons 973 * and visits), and is devoid of the binding information ordinarily 974 * available. 975 * </p> 976 * 977 * @return the return type, possibly the void primitive type 978 * @exception UnsupportedOperationException if this operation is used in 979 * an AST later than JLS2 980 * @deprecated In the JLS3 API, this method is replaced by {@link #getReturnType2()}, 981 * which may return <code>null</code>. 982 */ getReturnType()983 public Type getReturnType() { 984 return internalGetReturnType(); 985 } 986 987 /** 988 * Internal synonym for deprecated method. Used to avoid 989 * deprecation warnings. 990 * @exception UnsupportedOperationException if this operation is used in 991 * an AST later than JLS2 992 * @since 3.1 993 */ internalGetReturnType()994 /*package*/ final Type internalGetReturnType() { 995 supportedOnlyIn2(); 996 if (this.returnType == null) { 997 // lazy init must be thread-safe for readers 998 synchronized (this) { 999 if (this.returnType == null) { 1000 preLazyInit(); 1001 this.returnType = this.ast.newPrimitiveType(PrimitiveType.VOID); 1002 postLazyInit(this.returnType, RETURN_TYPE_PROPERTY); 1003 } 1004 } 1005 } 1006 return this.returnType; 1007 } 1008 1009 /** 1010 * Sets the return type of the method declared in this method declaration 1011 * to the given type, exclusive of any extra array dimensions (JLS2 API only). This is one 1012 * of the few places where the void type is meaningful. 1013 * <p> 1014 * Note that this child is not relevant for constructor declarations 1015 * (although it does still figure in subtree equality comparisons and visits). 1016 * </p> 1017 * 1018 * @param type the new return type, possibly the void primitive type 1019 * @exception IllegalArgumentException if: 1020 * <ul> 1021 * <li>the node belongs to a different AST</li> 1022 * <li>the node already has a parent</li> 1023 * </ul> 1024 * @exception UnsupportedOperationException if this operation is used in 1025 * an AST later than JLS2 1026 * @deprecated In the JLS3 API, this method is replaced by 1027 * {@link #setReturnType2(Type)}, which accepts <code>null</code>. 1028 */ setReturnType(Type type)1029 public void setReturnType(Type type) { 1030 internalSetReturnType(type); 1031 } 1032 1033 /** 1034 * Internal synonym for deprecated method. Used to avoid 1035 * deprecation warnings. 1036 * @since 3.1 1037 */ internalSetReturnType(Type type)1038 /*package*/ void internalSetReturnType(Type type) { 1039 supportedOnlyIn2(); 1040 if (type == null) { 1041 throw new IllegalArgumentException(); 1042 } 1043 ASTNode oldChild = this.returnType; 1044 preReplaceChild(oldChild, type, RETURN_TYPE_PROPERTY); 1045 this.returnType = type; 1046 postReplaceChild(oldChild, type, RETURN_TYPE_PROPERTY); 1047 } 1048 1049 /** 1050 * Returns the return type of the method declared in this method 1051 * declaration, exclusive of any extra array dimensions (added in JLS3 API). 1052 * This is one of the few places where the void type is meaningful. 1053 * <p> 1054 * Note that this child is not relevant for constructor declarations 1055 * (although, if present, it does still figure in subtree equality comparisons 1056 * and visits), and is devoid of the binding information ordinarily 1057 * available. In the JLS2 API, the return type is mandatory. 1058 * In the JLS3 API, the return type is optional. 1059 * </p> 1060 * 1061 * @return the return type, possibly the void primitive type, 1062 * or <code>null</code> if none 1063 * @exception UnsupportedOperationException if this operation is used in 1064 * a JLS2 AST 1065 * @since 3.1 1066 */ getReturnType2()1067 public Type getReturnType2() { 1068 unsupportedIn2(); 1069 if (this.returnType == null && !this.returnType2Initialized) { 1070 // lazy init must be thread-safe for readers 1071 synchronized (this) { 1072 if (this.returnType == null && !this.returnType2Initialized) { 1073 preLazyInit(); 1074 this.returnType = this.ast.newPrimitiveType(PrimitiveType.VOID); 1075 this.returnType2Initialized = true; 1076 postLazyInit(this.returnType, RETURN_TYPE2_PROPERTY); 1077 } 1078 } 1079 } 1080 return this.returnType; 1081 } 1082 1083 /** 1084 * Sets the return type of the method declared in this method declaration 1085 * to the given type, exclusive of any extra array dimensions (added in JLS3 API). 1086 * This is one of the few places where the void type is meaningful. 1087 * <p> 1088 * Note that this child is not relevant for constructor declarations 1089 * (although it does still figure in subtree equality comparisons and visits). 1090 * In the JLS2 API, the return type is mandatory. 1091 * In the JLS3 API, the return type is optional. 1092 * </p> 1093 * 1094 * @param type the new return type, possibly the void primitive type, 1095 * or <code>null</code> if none 1096 * @exception UnsupportedOperationException if this operation is used in 1097 * a JLS2 AST 1098 * @exception IllegalArgumentException if: 1099 * <ul> 1100 * <li>the node belongs to a different AST</li> 1101 * <li>the node already has a parent</li> 1102 * </ul> 1103 * @since 3.1 1104 */ setReturnType2(Type type)1105 public void setReturnType2(Type type) { 1106 unsupportedIn2(); 1107 this.returnType2Initialized = true; 1108 ASTNode oldChild = this.returnType; 1109 preReplaceChild(oldChild, type, RETURN_TYPE2_PROPERTY); 1110 this.returnType = type; 1111 postReplaceChild(oldChild, type, RETURN_TYPE2_PROPERTY); 1112 } 1113 1114 /** 1115 * Returns the number of extra array dimensions over and above the 1116 * explicitly-specified return type. 1117 * <p> 1118 * For example, <code>int foo()[][]</code> has a return type of 1119 * <code>int</code> and two extra array dimensions; 1120 * <code>int[][] foo()</code> has a return type of <code>int[][]</code> 1121 * and zero extra array dimensions. The two constructs have different 1122 * ASTs, even though there are really syntactic variants of the same 1123 * method declaration. 1124 * </p> 1125 * <p> 1126 * In the JLS8 API, this method is a convenience method that 1127 * counts {@link #extraDimensions()}. 1128 * </p> 1129 * 1130 * @return the number of extra array dimensions 1131 * @since 2.1 1132 */ getExtraDimensions()1133 public int getExtraDimensions() { 1134 // more efficient than checking getAST().API_LEVEL 1135 if (this.extraDimensions == null) { 1136 // JLS2,3,4 behavior - bona fide property 1137 return this.extraArrayDimensions; 1138 } else { 1139 return this.extraDimensions.size(); 1140 } 1141 } 1142 1143 /** 1144 * Sets the number of extra array dimensions over and above the 1145 * explicitly-specified return type. 1146 * <p> 1147 * For example, <code>int foo()[][]</code> is rendered as a return 1148 * type of <code>int</code> with two extra array dimensions; 1149 * <code>int[][] foo()</code> is rendered as a return type of 1150 * <code>int[][]</code> with zero extra array dimensions. The two 1151 * constructs have different ASTs, even though there are really syntactic 1152 * variants of the same method declaration. 1153 * </p> 1154 * 1155 * @param dimensions the number of array dimensions 1156 * @exception IllegalArgumentException if the number of dimensions is 1157 * negative 1158 * @exception UnsupportedOperationException if this operation is used in 1159 * a JLS8 or later AST 1160 * @since 2.1 1161 * @deprecated In the JLS8 API, this method is replaced by 1162 * {@link #extraDimensions()} which contains a list of {@link Dimension} nodes. 1163 */ setExtraDimensions(int dimensions)1164 public void setExtraDimensions(int dimensions) { 1165 // more efficient than just calling supportedOnlyIn2_3_4() to check 1166 if (this.extraDimensions != null) { 1167 supportedOnlyIn2_3_4(); 1168 } 1169 if (dimensions < 0) { 1170 throw new IllegalArgumentException(); 1171 } 1172 preValueChange(EXTRA_DIMENSIONS_PROPERTY); 1173 this.extraArrayDimensions = dimensions; 1174 postValueChange(EXTRA_DIMENSIONS_PROPERTY); 1175 } 1176 1177 /** 1178 * Returns the live ordered list of extra dimensions with optional annotations (added in JLS8 API). 1179 * 1180 * @return the live list of extra dimensions with optional annotations (element type: {@link Dimension}) 1181 * @exception UnsupportedOperationException if this operation is used below JLS8 1182 * @since 3.10 1183 */ extraDimensions()1184 public List extraDimensions() { 1185 // more efficient than just calling unsupportedIn2_3_4() to check 1186 if (this.extraDimensions == null) { 1187 unsupportedIn2_3_4(); 1188 } 1189 return this.extraDimensions; 1190 } 1191 1192 /** 1193 * Returns the body of this method declaration, or <code>null</code> if 1194 * this method has <b>no</b> body. 1195 * <p> 1196 * Note that there is a subtle difference between having no body and having 1197 * an empty body ("{}"). 1198 * </p> 1199 * 1200 * @return the method body, or <code>null</code> if this method has no 1201 * body 1202 */ getBody()1203 public Block getBody() { 1204 return this.optionalBody; 1205 } 1206 1207 /** 1208 * Sets or clears the body of this method declaration. 1209 * <p> 1210 * Note that there is a subtle difference between having no body 1211 * (as in <code>"void foo();"</code>) and having an empty body (as in 1212 * "void foo() {}"). Abstract methods, and methods declared in interfaces, 1213 * have no body. Non-abstract methods, and all constructors, have a body. 1214 * </p> 1215 * 1216 * @param body the block node, or <code>null</code> if 1217 * there is none 1218 * @exception IllegalArgumentException if: 1219 * <ul> 1220 * <li>the node belongs to a different AST</li> 1221 * <li>the node already has a parent</li> 1222 * <li>a cycle in would be created</li> 1223 * </ul> 1224 */ setBody(Block body)1225 public void setBody(Block body) { 1226 // a MethodDeclaration may occur in a Block - must check cycles 1227 ASTNode oldChild = this.optionalBody; 1228 preReplaceChild(oldChild, body, BODY_PROPERTY); 1229 this.optionalBody = body; 1230 postReplaceChild(oldChild, body, BODY_PROPERTY); 1231 } 1232 1233 /** 1234 * Resolves and returns the binding for the method or constructor declared 1235 * in this method or constructor declaration. 1236 * <p> 1237 * Note that bindings are generally unavailable unless requested when the 1238 * AST is being built. 1239 * </p> 1240 * 1241 * @return the binding, or <code>null</code> if the binding cannot be 1242 * resolved 1243 */ resolveBinding()1244 public IMethodBinding resolveBinding() { 1245 return this.ast.getBindingResolver().resolveMethod(this); 1246 } 1247 1248 @Override memSize()1249 int memSize() { 1250 return super.memSize() + 13 * 4; 1251 } 1252 1253 @Override treeSize()1254 int treeSize() { 1255 return 1256 memSize() 1257 + (this.optionalDocComment == null ? 0 : getJavadoc().treeSize()) 1258 + (this.modifiers == null ? 0 : this.modifiers.listSize()) 1259 + (this.typeParameters == null ? 0 : this.typeParameters.listSize()) 1260 + (this.methodName == null ? 0 : getName().treeSize()) 1261 + (this.optionalReceiverType == null ? 0 : this.optionalReceiverType.treeSize()) 1262 + (this.optionalReceiverQualifier == null ? 0 : this.optionalReceiverQualifier.treeSize()) 1263 + (this.returnType == null ? 0 : this.returnType.treeSize()) 1264 + this.parameters.listSize() 1265 + (this.ast.apiLevel < AST.JLS8_INTERNAL 1266 ? this.thrownExceptions.listSize() 1267 : this.extraDimensions.listSize() + this.thrownExceptionTypes.listSize()) 1268 + (this.optionalBody == null ? 0 : getBody().treeSize()); 1269 } 1270 } 1271 1272