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.lang.reflect.Constructor; 18 import java.lang.reflect.InvocationTargetException; 19 import java.util.ArrayList; 20 import java.util.Collections; 21 import java.util.HashMap; 22 import java.util.List; 23 import java.util.Map; 24 import java.util.StringTokenizer; 25 26 import org.eclipse.core.runtime.IProgressMonitor; 27 import org.eclipse.jdt.core.IClassFile; 28 import org.eclipse.jdt.core.ICompilationUnit; 29 import org.eclipse.jdt.core.IJavaProject; 30 import org.eclipse.jdt.core.JavaCore; 31 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 32 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; 33 import org.eclipse.jdt.internal.compiler.parser.Scanner; 34 import org.eclipse.jface.text.IDocument; 35 import org.eclipse.text.edits.TextEdit; 36 37 /** 38 * Umbrella owner and abstract syntax tree node factory. 39 * An <code>AST</code> instance serves as the common owner of any number of 40 * AST nodes, and as the factory for creating new AST nodes owned by that 41 * instance. 42 * <p> 43 * Abstract syntax trees may be hand constructed by clients, using the 44 * <code>new<i>TYPE</i></code> factory methods to create new nodes, and the 45 * various <code>set<i>CHILD</i></code> methods 46 * (see {@link org.eclipse.jdt.core.dom.ASTNode ASTNode} and its subclasses) 47 * to connect them together. 48 * </p> 49 * <p> 50 * Each AST node belongs to a unique AST instance, called the owning AST. 51 * The children of an AST node always have the same owner as their parent node. 52 * If a node from one AST is to be added to a different AST, the subtree must 53 * be cloned first to ensures that the added nodes have the correct owning AST. 54 * </p> 55 * <p> 56 * There can be any number of AST nodes owned by a single AST instance that are 57 * unparented. Each of these nodes is the root of a separate little tree of nodes. 58 * The method <code>ASTNode.getRoot()</code> navigates from any node to the root 59 * of the tree that it is contained in. Ordinarily, an AST instance has one main 60 * tree (rooted at a <code>CompilationUnit</code>), with newly-created nodes appearing 61 * as additional roots until they are parented somewhere under the main tree. 62 * One can navigate from any node to its AST instance, but not conversely. 63 * </p> 64 * <p> 65 * The class {@link ASTParser} parses a string 66 * containing a Java source code and returns an abstract syntax tree 67 * for it. The resulting nodes carry source ranges relating the node back to 68 * the original source characters. 69 * </p> 70 * <p> 71 * Compilation units created by <code>ASTParser</code> from a 72 * source document can be serialized after arbitrary modifications 73 * with minimal loss of original formatting. Here is an example: 74 * </p> 75 * <pre> 76 * Document doc = new Document("import java.util.List;\nclass X {}\n"); 77 * ASTParser parser = ASTParser.newParser(AST.JLS3); 78 * parser.setSource(doc.get().toCharArray()); 79 * CompilationUnit cu = (CompilationUnit) parser.createAST(null); 80 * cu.recordModifications(); 81 * AST ast = cu.getAST(); 82 * ImportDeclaration id = ast.newImportDeclaration(); 83 * id.setName(ast.newName(new String[] {"java", "util", "Set"}); 84 * cu.imports().add(id); // add import declaration at end 85 * TextEdit edits = cu.rewrite(document, null); 86 * UndoEdit undo = edits.apply(document); 87 * </pre> 88 * <p> 89 * See also {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite} for 90 * an alternative way to describe and serialize changes to a 91 * read-only AST. 92 * </p> 93 * <p> 94 * Clients may create instances of this class using {@link #newAST(int, boolean)}, 95 * but this class is not intended to be subclassed. 96 * </p> 97 * 98 * @see ASTParser 99 * @see ASTNode 100 * @since 2.0 101 * @noinstantiate This class is not intended to be instantiated by clients. 102 */ 103 @SuppressWarnings({ "rawtypes", "unchecked" }) 104 public final class AST { 105 /** 106 * new Class[] {AST.class} 107 * @since 3.0 108 */ 109 private static final Class[] AST_CLASS = new Class[] {AST.class}; 110 111 /** 112 * Constant for indicating the AST API that handles JLS2. 113 * <p> 114 * This API is capable of handling all constructs 115 * in the Java language as described in the Java Language 116 * Specification, Second Edition (JLS2). 117 * JLS2 is a superset of all earlier versions of the 118 * Java language, and the JLS2 API can be used to manipulate 119 * programs written in all versions of the Java language 120 * up to and including J2SE 1.4. 121 * </p> 122 * 123 * @since 3.0 124 * @deprecated Clients should use the {@link #JLS_Latest} AST API instead. 125 */ 126 public static final int JLS2 = 2; 127 128 /** 129 * Internal synonym for {@link #JLS2}. Use to alleviate 130 * deprecation warnings. 131 * @since 3.1 132 */ 133 /*package*/ static final int JLS2_INTERNAL = JLS2; 134 135 /** 136 * Constant for indicating the AST API that handles JLS3. 137 * <p> 138 * This API is capable of handling all constructs in the 139 * Java language as described in the Java Language 140 * Specification, Third Edition (JLS3). 141 * JLS3 is a superset of all earlier versions of the 142 * Java language, and the JLS3 API can be used to manipulate 143 * programs written in all versions of the Java language 144 * up to and including J2SE 5 (aka JDK 1.5). 145 * </p> 146 * 147 * @since 3.1 148 * @deprecated Clients should use the {@link #JLS_Latest} AST API instead. 149 */ 150 public static final int JLS3 = 3; 151 152 /** 153 * Internal synonym for {@link #JLS3}. Use to alleviate 154 * deprecation warnings. 155 * @since 3.8 156 */ 157 /*package*/ static final int JLS3_INTERNAL = JLS3; 158 159 /** 160 * Constant for indicating the AST API that handles JLS4 (aka JLS7). 161 * <p> 162 * This API is capable of handling all constructs in the 163 * Java language as described in the Java Language 164 * Specification, Java SE 7 Edition (JLS7) as specified by JSR336. 165 * JLS4 is a superset of all earlier versions of the 166 * Java language, and the JLS4 API can be used to manipulate 167 * programs written in all versions of the Java language 168 * up to and including Java SE 7 (aka JDK 1.7). 169 * </p> 170 * 171 * @since 3.7.1 172 * @deprecated Clients should use the {@link #JLS_Latest} AST API instead. 173 */ 174 public static final int JLS4 = 4; 175 176 /** 177 * Internal synonym for {@link #JLS4}. Use to alleviate 178 * deprecation warnings. 179 * @since 3.10 180 */ 181 /*package*/ static final int JLS4_INTERNAL = JLS4; 182 183 /** 184 * Constant for indicating the AST API that handles JLS8. 185 * <p> 186 * This API is capable of handling all constructs in the 187 * Java language as described in the Java Language 188 * Specification, Java SE 8 Edition (JLS8) as specified by JSR337. 189 * JLS8 is a superset of all earlier versions of the 190 * Java language, and the JLS8 API can be used to manipulate 191 * programs written in all versions of the Java language 192 * up to and including Java SE 8 (aka JDK 1.8). 193 * </p> 194 * 195 * @since 3.10 196 * @deprecated Clients should use the {@link #JLS_Latest} AST API instead. 197 */ 198 public static final int JLS8 = 8; 199 200 /** 201 * Internal synonym for {@link #JLS8}. Use to alleviate 202 * deprecation warnings. 203 * @since 3.14 204 */ 205 /*package*/ static final int JLS8_INTERNAL = JLS8; 206 207 /** 208 * Constant for indicating the AST API that handles JLS9. 209 * <p> 210 * This API is capable of handling all constructs in the 211 * Java language as described in the Java Language 212 * Specification, Java SE 9 Edition (JLS9). 213 * JLS9 is a superset of all earlier versions of the 214 * Java language, and the JLS9 API can be used to manipulate 215 * programs written in all versions of the Java language 216 * up to and including Java SE 9 (aka JDK 9). 217 * </p> 218 * 219 * @since 3.14 220 * @deprecated Clients should use the {@link #JLS_Latest} AST API instead. 221 */ 222 public static final int JLS9 = 9; 223 224 /** 225 * Internal synonym for {@link #JLS9}. Use to alleviate 226 * deprecation warnings once JLS9 is deprecated 227 * @since 3.14 228 */ 229 /*package*/ static final int JLS9_INTERNAL = JLS9; 230 231 /** 232 * Constant for indicating the AST API that handles JLS10. 233 * <p> 234 * This API is capable of handling all constructs in the 235 * Java language as described in the Java Language 236 * Specification, Java SE 10 Edition (JLS10). 237 * JLS10 is a superset of all earlier versions of the 238 * Java language, and the JLS10 API can be used to manipulate 239 * programs written in all versions of the Java language 240 * up to and including Java SE 10 (aka JDK 10). 241 * </p> 242 * 243 * @since 3.14 244 * @deprecated Clients should use the {@link #JLS_Latest} AST API instead. 245 */ 246 public static final int JLS10 = 10; 247 248 /** 249 * Internal synonym for {@link #JLS10}. Use to alleviate 250 * deprecation warnings once JLS10 is deprecated 251 * @since 3.14 252 */ 253 /*package*/ static final int JLS10_INTERNAL = JLS10; 254 255 /** 256 * Constant for indicating the AST API that handles JLS11. 257 * <p> 258 * This API is capable of handling all constructs in the 259 * Java language as described in the Java Language 260 * Specification, Java SE 11 Edition (JLS11). 261 * JLS11 is a superset of all earlier versions of the 262 * Java language, and the JLS11 API can be used to manipulate 263 * programs written in all versions of the Java language 264 * up to and including Java SE 11 (aka JDK 11). 265 * </p> 266 * 267 * @deprecated Clients should use the {@link #JLS_Latest} AST API instead. 268 * @since 3.16 269 */ 270 public static final int JLS11 = 11; 271 272 /** 273 * Internal synonym for {@link #JLS11}. Use to alleviate 274 * deprecation warnings once JLS11 is deprecated 275 * @since 3.14 276 */ 277 /*package*/ static final int JLS11_INTERNAL = JLS11; 278 279 /** 280 * Constant for indicating the AST API that handles JLS12. 281 * <p> 282 * This API is capable of handling all constructs in the 283 * Java language as described in the Java Language 284 * Specification, Java SE 12 Edition (JLS12). 285 * JLS12 is a superset of all earlier versions of the 286 * Java language, and the JLS12 API can be used to manipulate 287 * programs written in all versions of the Java language 288 * up to and including Java SE 12 (aka JDK 12). 289 * </p> 290 * @deprecated Clients should use the {@link #JLS_Latest} AST API instead. 291 * @since 3.18 292 */ 293 public static final int JLS12 = 12; 294 /** 295 * Internal synonym for {@link #JLS12}. Use to alleviate 296 * deprecation warnings once JLS12 is deprecated 297 * @since 3.18 298 */ 299 static final int JLS12_INTERNAL = JLS12; 300 301 /** 302 * Constant for indicating the AST API that handles JLS13. 303 * <p> 304 * This API is capable of handling all constructs in the 305 * Java language as described in the Java Language 306 * Specification, Java SE 13 Edition (JLS13). 307 * JLS13 is a superset of all earlier versions of the 308 * Java language, and the JLS13 API can be used to manipulate 309 * programs written in all versions of the Java language 310 * up to and including Java SE 13 (aka JDK 13). 311 * </p> 312 * 313 * @since 3.20 314 * @deprecated Clients should use the {@link #JLS_Latest} AST API instead. 315 */ 316 public static final int JLS13 = 13; 317 318 /** 319 * Internal synonym for {@link #JLS13}. Use to alleviate 320 * deprecation warnings once JLS13 is deprecated 321 * @since 3.20 322 */ 323 static final int JLS13_INTERNAL = JLS13; 324 325 /** 326 * Constant for indicating the AST API that handles JLS14. 327 * <p> 328 * This API is capable of handling all constructs in the 329 * Java language as described in the Java Language 330 * Specification, Java SE 14 Edition (JLS14). 331 * JLS14 is a superset of all earlier versions of the 332 * Java language, and the JLS14 API can be used to manipulate 333 * programs written in all versions of the Java language 334 * up to and including Java SE 14(aka JDK 14). 335 * </p> 336 * 337 * @since 3.22 338 */ 339 public static final int JLS14 = 14; 340 341 /** 342 * Internal synonym for {@link #JLS14}. Use to alleviate 343 * deprecation warnings once JLS14 is deprecated 344 * @since 3.22 345 */ 346 static final int JLS14_INTERNAL = JLS14; 347 348 @SuppressWarnings("unused") 349 /* Used for Java doc only*/ 350 private static final int JLS_Latest = JLS14; 351 352 /* 353 * Must not collide with a value for ICompilationUnit constants 354 */ 355 static final int RESOLVED_BINDINGS = 0x80000000; 356 357 private static Map<String, Long> jdkLevelMap = getLevelMapTable(); 358 359 private static Map<String, Integer> apiLevelMap = getApiLevelMapTable(); 360 361 /** 362 * Internal method. 363 * <p> 364 * This method converts the given internal compiler AST for the given source string 365 * into a compilation unit. This method is not intended to be called by clients. 366 * </p> 367 * 368 * @param level the API level; one of the <code>JLS*</code> level constants 369 * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration 370 * @param source the string of the Java compilation unit 371 * @param options compiler options 372 * @param workingCopy the working copy that the AST is created from 373 * @param monitor the progress monitor used to report progress and request cancellation, 374 * or <code>null</code> if none 375 * @param isResolved whether the given compilation unit declaration is resolved 376 * @return the compilation unit node 377 * @deprecated Use org.eclipse.jdt.core.dom.AST.convertCompilationUnit(int, CompilationUnitDeclaration, Map, boolean, CompilationUnit, int, IProgressMonitor) instead 378 * @noreference This method is not intended to be referenced by clients. 379 */ convertCompilationUnit( int level, org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration, char[] source, Map options, boolean isResolved, org.eclipse.jdt.internal.core.CompilationUnit workingCopy, int reconcileFlags, IProgressMonitor monitor)380 public static CompilationUnit convertCompilationUnit( 381 int level, 382 org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration, 383 char[] source, 384 Map options, 385 boolean isResolved, 386 org.eclipse.jdt.internal.core.CompilationUnit workingCopy, 387 int reconcileFlags, 388 IProgressMonitor monitor) { 389 return null; 390 } 391 392 /** 393 * Internal method. 394 * <p> 395 * This method converts the given internal compiler AST for the given source string 396 * into a compilation unit. This method is not intended to be called by clients. 397 * </p> 398 * 399 * @param level the API level; one of the <code>JLS*</code> level constants 400 * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration 401 * @param options compiler options 402 * @param workingCopy the working copy that the AST is created from 403 * @param monitor the progress monitor used to report progress and request cancellation, 404 * or <code>null</code> if none 405 * @param isResolved whether the given compilation unit declaration is resolved 406 * @return the compilation unit node 407 * @since 3.4 408 * @noreference This method is not intended to be referenced by clients. 409 */ convertCompilationUnit( int level, org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration, Map options, boolean isResolved, org.eclipse.jdt.internal.core.CompilationUnit workingCopy, int reconcileFlags, IProgressMonitor monitor)410 public static CompilationUnit convertCompilationUnit( 411 int level, 412 org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration, 413 Map options, 414 boolean isResolved, 415 org.eclipse.jdt.internal.core.CompilationUnit workingCopy, 416 int reconcileFlags, 417 IProgressMonitor monitor) { 418 419 ASTConverter converter = new ASTConverter(options, isResolved, monitor); 420 AST ast = AST.newAST(level, JavaCore.ENABLED.equals(options.get(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES))); 421 String sourceModeSetting = (String) options.get(JavaCore.COMPILER_SOURCE); 422 long sourceLevel = CompilerOptions.versionToJdkLevel(sourceModeSetting); 423 if (sourceLevel == 0) { 424 // unknown sourceModeSetting 425 sourceLevel = ClassFileConstants.JDK1_3; 426 } 427 ast.scanner.sourceLevel = sourceLevel; 428 String compliance = (String) options.get(JavaCore.COMPILER_COMPLIANCE); 429 long complianceLevel = CompilerOptions.versionToJdkLevel(compliance); 430 if (complianceLevel == 0) { 431 // unknown sourceModeSetting 432 complianceLevel = sourceLevel; 433 } 434 ast.scanner.complianceLevel = complianceLevel; 435 ast.scanner.previewEnabled = JavaCore.ENABLED.equals(options.get(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES)); 436 int savedDefaultNodeFlag = ast.getDefaultNodeFlag(); 437 ast.setDefaultNodeFlag(ASTNode.ORIGINAL); 438 BindingResolver resolver = null; 439 if (isResolved) { 440 resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope, workingCopy.owner, new DefaultBindingResolver.BindingTables(), false, true); 441 ((DefaultBindingResolver) resolver).isRecoveringBindings = (reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0; 442 ast.setFlag(AST.RESOLVED_BINDINGS); 443 } else { 444 resolver = new BindingResolver(); 445 } 446 ast.setFlag(reconcileFlags); 447 ast.setBindingResolver(resolver); 448 converter.setAST(ast); 449 450 CompilationUnit unit = converter.convert(compilationUnitDeclaration, workingCopy.getContents()); 451 unit.setLineEndTable(compilationUnitDeclaration.compilationResult.getLineSeparatorPositions()); 452 unit.setTypeRoot(workingCopy.originalFromClone()); 453 ast.setDefaultNodeFlag(savedDefaultNodeFlag); 454 return unit; 455 } 456 457 /** 458 * Creates a new Java abstract syntax tree 459 * (AST) following the specified set of API rules. 460 * <p> 461 * Clients should use this method specifying {@link #JLS12} as the 462 * AST level in all cases, even when dealing with source of earlier JDK versions like 1.3 or 1.4. 463 * </p> 464 * 465 * @param level the API level; one of the <code>JLS*</code> level constants 466 * @return new AST instance following the specified set of API rules. 467 * @exception IllegalArgumentException if: 468 * <ul> 469 * <li>the API level is not one of the <code>JLS*</code> level constants</li> 470 * </ul> 471 * @deprecated Clients should port their code to use the latest JLS* AST API and call 472 * {@link #newAST(int, boolean) AST.newAST(AST.JLS12, false)} instead of using this constructor. 473 * @since 3.0 474 */ newAST(int level)475 public static AST newAST(int level) { 476 return new AST(level, false); 477 } 478 479 /** 480 * Creates a new Java abstract syntax tree 481 * (AST) following the specified set of API rules. 482 * <p> 483 * Clients should use this method specifying {@link #JLS12} as the 484 * AST level in all cases, even when dealing with source of earlier JDK versions like 1.3 or 1.4. 485 * </p> 486 * 487 * @param level the API level; one of the <code>JLS*</code> level constants 488 * @param previewEnabled <code>true</code> if preview feature is enabled else <code>false</code> 489 * @return new AST instance following the specified set of API rules. 490 * @exception IllegalArgumentException if: 491 * <ul> 492 * <li>the API level is not one of the <code>JLS*</code> level constants</li> 493 * </ul> 494 * @since 3.19 495 */ newAST(int level, boolean previewEnabled)496 public static AST newAST(int level, boolean previewEnabled) { 497 return new AST(level, previewEnabled); 498 } 499 500 /** 501 * Creates a new Java abstract syntax tree 502 * Following option keys are significant: 503 * <ul> 504 * <li><code>"org.eclipse.jdt.core.compiler.source"</code> 505 * indicates the api level and source compatibility mode (as per <code>JavaCore</code>) - defaults to 1.3 506 * <ul> 507 * <li> 508 * <code>"1.3"</code> means the source code is as per JDK 1.3 and api level {@link #JLS3}.</li> 509 * <li><code>"1.4", "1.5", "1.6", "1.7" "1.8"</code> implies the respective source JDK levels 1.4, 1.5, 1.6, 1.7 and api level {@link #JLS4}.</li> 510 * <li><code>"1.8"</code> implies the respective source JDK level 1.8 and api level {@link #JLS8}.</li> 511 * <li><code>"9", "10", "11", "12" and "13"</code> implies the respective JDK levels 9, 10, 11, 12 and 13 512 * and api levels {@link #JLS9}, {@link #JLS10}, {@link #JLS11}, {@link #JLS12} and {@link #JLS13}.</li> 513 * <li>Additional legal values may be added later.</li> 514 * </ul> 515 * </li> 516 * <li><code>"org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures"</code> - 517 * indicates whether the preview is enabled or disabled 518 * legal values are <code>"enabled"</code> and <code>"disabled"</code> implying preview enabled and disabled respectively. 519 * preview enabling has an effect only with the latest ast level. 520 * </li> 521 * </ul> 522 * 523 * @param options the table of options 524 * @see JavaCore#getDefaultOptions() 525 * @since 3.20 526 */ newAST(Map<String, String> options)527 public static AST newAST(Map<String, String> options) { 528 return new AST(options); 529 } 530 /** 531 * Parses the given string as a Java compilation unit and creates and 532 * returns a corresponding abstract syntax tree. 533 * <p> 534 * The returned compilation unit node is the root node of a new AST. 535 * Each node in the subtree carries source range(s) information relating back 536 * to positions in the given source string (the given source string itself 537 * is not remembered with the AST). 538 * The source range usually begins at the first character of the first token 539 * corresponding to the node; leading whitespace and comments are <b>not</b> 540 * included. The source range usually extends through the last character of 541 * the last token corresponding to the node; trailing whitespace and 542 * comments are <b>not</b> included. There are a handful of exceptions 543 * (including compilation units and the various body declarations); the 544 * specification for these node type spells out the details. 545 * Source ranges nest properly: the source range for a child is always 546 * within the source range of its parent, and the source ranges of sibling 547 * nodes never overlap. 548 * If a syntax error is detected while parsing, the relevant node(s) of the 549 * tree will be flagged as <code>MALFORMED</code>. 550 * </p> 551 * <p> 552 * This method does not compute binding information; all <code>resolveBinding</code> 553 * methods applied to nodes of the resulting AST return <code>null</code>. 554 * </p> 555 * 556 * @param source the string to be parsed as a Java compilation unit 557 * @return the compilation unit node 558 * @see ASTNode#getFlags() 559 * @see ASTNode#MALFORMED 560 * @see ASTNode#getStartPosition() 561 * @see ASTNode#getLength() 562 * @since 2.0 563 * @deprecated Use {@link ASTParser} instead. 564 */ parseCompilationUnit(char[] source)565 public static CompilationUnit parseCompilationUnit(char[] source) { 566 if (source == null) { 567 throw new IllegalArgumentException(); 568 } 569 ASTParser c = ASTParser.newParser(AST.JLS2); 570 c.setSource(source); 571 ASTNode result = c.createAST(null); 572 return (CompilationUnit) result; 573 } 574 575 /** 576 * Parses the given string as the hypothetical contents of the named 577 * compilation unit and creates and returns a corresponding abstract syntax tree. 578 * <p> 579 * The returned compilation unit node is the root node of a new AST. 580 * Each node in the subtree carries source range(s) information relating back 581 * to positions in the given source string (the given source string itself 582 * is not remembered with the AST). 583 * The source range usually begins at the first character of the first token 584 * corresponding to the node; leading whitespace and comments are <b>not</b> 585 * included. The source range usually extends through the last character of 586 * the last token corresponding to the node; trailing whitespace and 587 * comments are <b>not</b> included. There are a handful of exceptions 588 * (including compilation units and the various body declarations); the 589 * specification for these node type spells out the details. 590 * Source ranges nest properly: the source range for a child is always 591 * within the source range of its parent, and the source ranges of sibling 592 * nodes never overlap. 593 * If a syntax error is detected while parsing, the relevant node(s) of the 594 * tree will be flagged as <code>MALFORMED</code>. 595 * </p> 596 * <p> 597 * If the given project is not <code>null</code>, the various names 598 * and types appearing in the compilation unit can be resolved to "bindings" 599 * by calling the <code>resolveBinding</code> methods. These bindings 600 * draw connections between the different parts of a program, and 601 * generally afford a more powerful vantage point for clients who wish to 602 * analyze a program's structure more deeply. These bindings come at a 603 * considerable cost in both time and space, however, and should not be 604 * requested frivolously. The additional space is not reclaimed until the 605 * AST, all its nodes, and all its bindings become garbage. So it is very 606 * important to not retain any of these objects longer than absolutely 607 * necessary. Bindings are resolved at the time the AST is created. Subsequent 608 * modifications to the AST do not affect the bindings returned by 609 * <code>resolveBinding</code> methods in any way; these methods return the 610 * same binding as before the AST was modified (including modifications 611 * that rearrange subtrees by reparenting nodes). 612 * If the given project is <code>null</code>, the analysis 613 * does not go beyond parsing and building the tree, and all 614 * <code>resolveBinding</code> methods return <code>null</code> from the 615 * outset. 616 * </p> 617 * <p> 618 * The name of the compilation unit must be supplied for resolving bindings. 619 * This name should be suffixed by a dot ('.') followed by one of the 620 * {@link JavaCore#getJavaLikeExtensions() Java-like extensions} 621 * and match the name of the main 622 * (public) class or interface declared in the source. For example, if the source 623 * declares a public class named "Foo", the name of the compilation can be 624 * "Foo.java". For the purposes of resolving bindings, types declared in the 625 * source string hide types by the same name available through the classpath 626 * of the given project. 627 * </p> 628 * 629 * @param source the string to be parsed as a Java compilation unit 630 * @param unitName the name of the compilation unit that would contain the source 631 * string, or <code>null</code> if <code>javaProject</code> is also <code>null</code> 632 * @param project the Java project used to resolve names, or 633 * <code>null</code> if bindings are not resolved 634 * @return the compilation unit node 635 * @see ASTNode#getFlags() 636 * @see ASTNode#MALFORMED 637 * @see ASTNode#getStartPosition() 638 * @see ASTNode#getLength() 639 * @since 2.0 640 * @deprecated Use {@link ASTParser} instead. 641 */ parseCompilationUnit( char[] source, String unitName, IJavaProject project)642 public static CompilationUnit parseCompilationUnit( 643 char[] source, 644 String unitName, 645 IJavaProject project) { 646 647 if (source == null) { 648 throw new IllegalArgumentException(); 649 } 650 ASTParser astParser = ASTParser.newParser(AST.JLS2); 651 astParser.setSource(source); 652 astParser.setUnitName(unitName); 653 astParser.setProject(project); 654 astParser.setResolveBindings(project != null); 655 ASTNode result = astParser.createAST(null); 656 return (CompilationUnit) result; 657 } 658 659 /** 660 * Parses the source string corresponding to the given Java class file 661 * element and creates and returns a corresponding abstract syntax tree. 662 * The source string is obtained from the Java model element using 663 * <code>IClassFile.getSource()</code>, and is only available for a class 664 * files with attached source. 665 * <p> 666 * The returned compilation unit node is the root node of a new AST. 667 * Each node in the subtree carries source range(s) information relating back 668 * to positions in the source string (the source string is not remembered 669 * with the AST). 670 * The source range usually begins at the first character of the first token 671 * corresponding to the node; leading whitespace and comments are <b>not</b> 672 * included. The source range usually extends through the last character of 673 * the last token corresponding to the node; trailing whitespace and 674 * comments are <b>not</b> included. There are a handful of exceptions 675 * (including compilation units and the various body declarations); the 676 * specification for these node type spells out the details. 677 * Source ranges nest properly: the source range for a child is always 678 * within the source range of its parent, and the source ranges of sibling 679 * nodes never overlap. 680 * If a syntax error is detected while parsing, the relevant node(s) of the 681 * tree will be flagged as <code>MALFORMED</code>. 682 * </p> 683 * <p> 684 * If <code>resolveBindings</code> is <code>true</code>, the various names 685 * and types appearing in the compilation unit can be resolved to "bindings" 686 * by calling the <code>resolveBinding</code> methods. These bindings 687 * draw connections between the different parts of a program, and 688 * generally afford a more powerful vantage point for clients who wish to 689 * analyze a program's structure more deeply. These bindings come at a 690 * considerable cost in both time and space, however, and should not be 691 * requested frivolously. The additional space is not reclaimed until the 692 * AST, all its nodes, and all its bindings become garbage. So it is very 693 * important to not retain any of these objects longer than absolutely 694 * necessary. Bindings are resolved at the time the AST is created. Subsequent 695 * modifications to the AST do not affect the bindings returned by 696 * <code>resolveBinding</code> methods in any way; these methods return the 697 * same binding as before the AST was modified (including modifications 698 * that rearrange subtrees by reparenting nodes). 699 * If <code>resolveBindings</code> is <code>false</code>, the analysis 700 * does not go beyond parsing and building the tree, and all 701 * <code>resolveBinding</code> methods return <code>null</code> from the 702 * outset. 703 * </p> 704 * 705 * @param classFile the Java model class file whose corresponding source code is to be parsed 706 * @param resolveBindings <code>true</code> if bindings are wanted, 707 * and <code>false</code> if bindings are not of interest 708 * @return the compilation unit node 709 * @exception IllegalArgumentException if the given Java element does not 710 * exist or if its source string cannot be obtained 711 * @see ASTNode#getFlags() 712 * @see ASTNode#MALFORMED 713 * @see ASTNode#getStartPosition() 714 * @see ASTNode#getLength() 715 * @since 2.1 716 * @deprecated Use {@link ASTParser} instead. 717 */ parseCompilationUnit( IClassFile classFile, boolean resolveBindings)718 public static CompilationUnit parseCompilationUnit( 719 IClassFile classFile, 720 boolean resolveBindings) { 721 722 if (classFile == null) { 723 throw new IllegalArgumentException(); 724 } 725 try { 726 ASTParser c = ASTParser.newParser(AST.JLS2); 727 c.setSource(classFile); 728 c.setResolveBindings(resolveBindings); 729 ASTNode result = c.createAST(null); 730 return (CompilationUnit) result; 731 } catch (IllegalStateException e) { 732 // convert ASTParser's complaints into old form 733 throw new IllegalArgumentException(e); 734 } 735 } 736 737 /** 738 * Parses the source string of the given Java model compilation unit element 739 * and creates and returns a corresponding abstract syntax tree. The source 740 * string is obtained from the Java model element using 741 * <code>ICompilationUnit.getSource()</code>. 742 * <p> 743 * The returned compilation unit node is the root node of a new AST. 744 * Each node in the subtree carries source range(s) information relating back 745 * to positions in the source string (the source string is not remembered 746 * with the AST). 747 * The source range usually begins at the first character of the first token 748 * corresponding to the node; leading whitespace and comments are <b>not</b> 749 * included. The source range usually extends through the last character of 750 * the last token corresponding to the node; trailing whitespace and 751 * comments are <b>not</b> included. There are a handful of exceptions 752 * (including compilation units and the various body declarations); the 753 * specification for these node type spells out the details. 754 * Source ranges nest properly: the source range for a child is always 755 * within the source range of its parent, and the source ranges of sibling 756 * nodes never overlap. 757 * If a syntax error is detected while parsing, the relevant node(s) of the 758 * tree will be flagged as <code>MALFORMED</code>. 759 * </p> 760 * <p> 761 * If <code>resolveBindings</code> is <code>true</code>, the various names 762 * and types appearing in the compilation unit can be resolved to "bindings" 763 * by calling the <code>resolveBinding</code> methods. These bindings 764 * draw connections between the different parts of a program, and 765 * generally afford a more powerful vantage point for clients who wish to 766 * analyze a program's structure more deeply. These bindings come at a 767 * considerable cost in both time and space, however, and should not be 768 * requested frivolously. The additional space is not reclaimed until the 769 * AST, all its nodes, and all its bindings become garbage. So it is very 770 * important to not retain any of these objects longer than absolutely 771 * necessary. Bindings are resolved at the time the AST is created. Subsequent 772 * modifications to the AST do not affect the bindings returned by 773 * <code>resolveBinding</code> methods in any way; these methods return the 774 * same binding as before the AST was modified (including modifications 775 * that rearrange subtrees by reparenting nodes). 776 * If <code>resolveBindings</code> is <code>false</code>, the analysis 777 * does not go beyond parsing and building the tree, and all 778 * <code>resolveBinding</code> methods return <code>null</code> from the 779 * outset. 780 * </p> 781 * 782 * @param unit the Java model compilation unit whose source code is to be parsed 783 * @param resolveBindings <code>true</code> if bindings are wanted, 784 * and <code>false</code> if bindings are not of interest 785 * @return the compilation unit node 786 * @exception IllegalArgumentException if the given Java element does not 787 * exist or if its source string cannot be obtained 788 * @see ASTNode#getFlags() 789 * @see ASTNode#MALFORMED 790 * @see ASTNode#getStartPosition() 791 * @see ASTNode#getLength() 792 * @since 2.0 793 * @deprecated Use {@link ASTParser} instead. 794 */ parseCompilationUnit( ICompilationUnit unit, boolean resolveBindings)795 public static CompilationUnit parseCompilationUnit( 796 ICompilationUnit unit, 797 boolean resolveBindings) { 798 799 try { 800 ASTParser c = ASTParser.newParser(AST.JLS2); 801 c.setSource(unit); 802 c.setResolveBindings(resolveBindings); 803 ASTNode result = c.createAST(null); 804 return (CompilationUnit) result; 805 } catch (IllegalStateException e) { 806 // convert ASTParser's complaints into old form 807 throw new IllegalArgumentException(e); 808 } 809 } 810 811 /** 812 * Level of AST API supported by this AST. 813 * @since 3.0 814 */ 815 int apiLevel; 816 817 private boolean previewEnabled; 818 819 /** 820 * Tag bit value. This represents internal state of the tree. 821 */ 822 private int bits; 823 824 /** 825 * Default value of <code>flag<code> when a new node is created. 826 */ 827 private int defaultNodeFlag = 0; 828 829 /** 830 * When disableEvents > 0, events are not reported and 831 * the modification count stays fixed. 832 * <p> 833 * This mechanism is used in lazy initialization of a node 834 * to prevent events from being reported for the modification 835 * of the node as well as for the creation of the missing child. 836 * </p> 837 * @since 3.0 838 */ 839 private int disableEvents = 0; 840 841 /** 842 * The event handler for this AST. 843 * Initially an event handler that does not nothing. 844 * @since 3.0 845 */ 846 private NodeEventHandler eventHandler = new NodeEventHandler(); 847 848 /** 849 * Internal object unique to the AST instance. Readers must synchronize on 850 * this object when the modifying instance fields. 851 * @since 3.0 852 */ 853 private final Object internalASTLock = new Object(); 854 855 /** 856 * Internal modification count; initially 0; increases monotonically 857 * <b>by one or more</b> as the AST is successively modified. 858 */ 859 private long modificationCount = 0; 860 861 /** 862 * Internal original modification count; value is equals to <code> 863 * modificationCount</code> at the end of the parse (<code>ASTParser 864 * </code>). If this ast is not created with a parser then value is 0. 865 * @since 3.0 866 */ 867 private long originalModificationCount = 0; 868 869 /** 870 * The binding resolver for this AST. Initially a binding resolver that 871 * does not resolve names at all. 872 */ 873 private BindingResolver resolver = new BindingResolver(); 874 875 /** 876 * Internal ast rewriter used to record ast modification when record mode is enabled. 877 */ 878 InternalASTRewrite rewriter; 879 880 /** 881 * Java Scanner used to validate preconditions for the creation of specific nodes 882 * like CharacterLiteral, NumberLiteral, StringLiteral or SimpleName. 883 */ 884 Scanner scanner; 885 886 /** 887 * new Object[] {this} 888 * @since 3.0 889 */ 890 private final Object[] THIS_AST= new Object[] {this}; 891 892 /** 893 * Creates a new, empty abstract syntax tree using default options. 894 * 895 * @see JavaCore#getDefaultOptions() 896 * @deprecated Clients should port their code to use the latest JLS* AST API and call 897 * {@link #newAST(int, boolean) AST.newAST(AST.JLS12, false)} instead of using this constructor. 898 */ AST()899 public AST() { 900 this(JavaCore.getDefaultOptions()); 901 } 902 903 /** 904 * Creates a new Java abstract syntax tree 905 * (AST) following the specified set of API rules. 906 * 907 * @param level the API level; one of the <code>JLS*</code> level constants 908 * @since 3.0 909 */ AST(int level, boolean previewEnabled)910 private AST(int level, boolean previewEnabled) { 911 this.previewEnabled = previewEnabled; 912 switch(level) { 913 case JLS2_INTERNAL : 914 case JLS3_INTERNAL : 915 this.apiLevel = level; 916 // initialize a scanner 917 this.scanner = new Scanner( 918 true /*comment*/, 919 true /*whitespace*/, 920 false /*nls*/, 921 ClassFileConstants.JDK1_3 /*sourceLevel*/, 922 ClassFileConstants.JDK1_5 /*complianceLevel*/, 923 null/*taskTag*/, 924 null/*taskPriorities*/, 925 true/*taskCaseSensitive*/, 926 false/*isPreviewEnabled*/); 927 break; 928 case JLS4_INTERNAL : 929 this.apiLevel = level; 930 // initialize a scanner 931 this.scanner = new Scanner( 932 true /*comment*/, 933 true /*whitespace*/, 934 false /*nls*/, 935 ClassFileConstants.JDK1_7 /*sourceLevel*/, 936 ClassFileConstants.JDK1_7 /*complianceLevel*/, 937 null/*taskTag*/, 938 null/*taskPriorities*/, 939 true/*taskCaseSensitive*/, 940 false/*isPreviewEnabled*/); 941 break; 942 case JLS8_INTERNAL : 943 this.apiLevel = level; 944 // initialize a scanner 945 this.scanner = new Scanner( 946 true /*comment*/, 947 true /*whitespace*/, 948 false /*nls*/, 949 ClassFileConstants.JDK1_8 /*sourceLevel*/, 950 ClassFileConstants.JDK1_8 /*complianceLevel*/, 951 null/*taskTag*/, 952 null/*taskPriorities*/, 953 true/*taskCaseSensitive*/, 954 false/*isPreviewEnabled*/); 955 break; 956 case JLS9_INTERNAL : 957 this.apiLevel = level; 958 // initialize a scanner 959 this.scanner = new Scanner( 960 true /*comment*/, 961 true /*whitespace*/, 962 false /*nls*/, 963 ClassFileConstants.JDK9 /*sourceLevel*/, 964 ClassFileConstants.JDK9 /*complianceLevel*/, 965 null/*taskTag*/, 966 null/*taskPriorities*/, 967 true/*taskCaseSensitive*/, 968 false/*isPreviewEnabled*/); 969 break; 970 case JLS10_INTERNAL : 971 this.apiLevel = level; 972 // initialize a scanner 973 this.scanner = new Scanner( 974 true /*comment*/, 975 true /*whitespace*/, 976 false /*nls*/, 977 ClassFileConstants.JDK10 /*sourceLevel*/, 978 ClassFileConstants.JDK10 /*complianceLevel*/, 979 null/*taskTag*/, 980 null/*taskPriorities*/, 981 true/*taskCaseSensitive*/, 982 false/*isPreviewEnabled*/); 983 break; 984 case JLS11_INTERNAL : 985 this.apiLevel = level; 986 // initialize a scanner 987 long compliance = ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11); 988 this.scanner = new Scanner( 989 true /*comment*/, 990 true /*whitespace*/, 991 false /*nls*/, 992 compliance /*sourceLevel*/, 993 compliance /*complianceLevel*/, 994 null/*taskTag*/, 995 null/*taskPriorities*/, 996 true/*taskCaseSensitive*/, 997 false/*isPreviewEnabled*/); 998 break; 999 case JLS12_INTERNAL : 1000 this.apiLevel = level; 1001 // initialize a scanner 1002 compliance = ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12); 1003 this.scanner = new Scanner( 1004 true /*comment*/, 1005 true /*whitespace*/, 1006 false /*nls*/, 1007 compliance /*sourceLevel*/, 1008 compliance /*complianceLevel*/, 1009 null/*taskTag*/, 1010 null/*taskPriorities*/, 1011 true/*taskCaseSensitive*/, 1012 previewEnabled); 1013 break; 1014 case JLS13_INTERNAL : 1015 this.apiLevel = level; 1016 // initialize a scanner 1017 compliance = ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_13); 1018 this.scanner = new Scanner( 1019 true /*comment*/, 1020 true /*whitespace*/, 1021 false /*nls*/, 1022 compliance /*sourceLevel*/, 1023 compliance /*complianceLevel*/, 1024 null/*taskTag*/, 1025 null/*taskPriorities*/, 1026 true/*taskCaseSensitive*/, 1027 previewEnabled); 1028 break; 1029 case JLS14_INTERNAL : 1030 this.apiLevel = level; 1031 // initialize a scanner 1032 compliance = ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_14); 1033 this.scanner = new Scanner( 1034 true /*comment*/, 1035 true /*whitespace*/, 1036 false /*nls*/, 1037 compliance /*sourceLevel*/, 1038 compliance /*complianceLevel*/, 1039 null/*taskTag*/, 1040 null/*taskPriorities*/, 1041 true/*taskCaseSensitive*/, 1042 previewEnabled); 1043 break; 1044 default: 1045 throw new IllegalArgumentException("Unsupported JLS level"); //$NON-NLS-1$ 1046 } 1047 } 1048 1049 /** 1050 * Creates a new Java abstract syntax tree 1051 * Following option keys are significant: 1052 * <ul> 1053 * <li><code>"org.eclipse.jdt.core.compiler.source"</code> 1054 * indicates the api level and source compatibility mode (as per <code>JavaCore</code>) - defaults to 1.3 1055 * <ul> 1056 * <li> 1057 * <code>"1.3"</code> means the source code is as per JDK 1.3 and api level {@link #JLS3}.</li> 1058 * <li><code>"1.4", "1.5", "1.6", "1.7" "1.8"</code> implies the respective source JDK levels 1.4, 1.5, 1.6, 1.7 and api level {@link #JLS4}.</li> 1059 * <li><code>"1.8"</code> implies the respective source JDK level 1.8 and api level {@link #JLS8}.</li> 1060 * <li><code>"9", "10", "11", "12" and "13"</code> implies the respective JDK levels 9, 10, 11, 12 and 13 1061 * and api levels {@link #JLS9}, {@link #JLS10}, {@link #JLS11}, {@link #JLS12} and {@link #JLS13}.</li> 1062 * <li>Additional legal values may be added later.</li> 1063 * </ul> 1064 * <li><code>"org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures"</code> - 1065 * indicates whether the preview is enabled or disabled 1066 * legal values are <code>"enabled"</code> and <code>"disabled"</code> implying preview enabled and disabled respectively. 1067 * preview enabling has an effect only with the latest ast level. 1068 * </li> 1069 * </ul> 1070 * 1071 * @param options the table of options (key type: <code>String</code>; 1072 * value type: <code>String</code>) 1073 * @see JavaCore#getDefaultOptions() 1074 */ AST(Map options)1075 public AST(Map options) { 1076 this(apiLevelMap.get(options.get(JavaCore.COMPILER_SOURCE)), 1077 JavaCore.ENABLED.equals(options.get(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES))); 1078 1079 long sourceLevel; 1080 long complianceLevel; 1081 switch(this.apiLevel) { 1082 case JLS2_INTERNAL : 1083 case JLS3_INTERNAL : 1084 sourceLevel = ClassFileConstants.JDK1_3; 1085 complianceLevel = ClassFileConstants.JDK1_5; 1086 break; 1087 case JLS4_INTERNAL : 1088 sourceLevel = ClassFileConstants.JDK1_7; 1089 complianceLevel = ClassFileConstants.JDK1_7; 1090 break; 1091 default : 1092 sourceLevel = AST.jdkLevelMap.get(options.get(JavaCore.COMPILER_SOURCE)); 1093 complianceLevel = sourceLevel; 1094 } 1095 this.scanner = new Scanner( 1096 true /*comment*/, 1097 true /*whitespace*/, 1098 false /*nls*/, 1099 sourceLevel /*sourceLevel*/, 1100 complianceLevel /*complianceLevel*/, 1101 null/*taskTag*/, 1102 null/*taskPriorities*/, 1103 true/*taskCaseSensitive*/, 1104 this.previewEnabled /* isPreviewEnabled*/); 1105 } 1106 getLevelMapTable()1107 private static Map<String, Long> getLevelMapTable() { 1108 Map<String, Long> t = new HashMap<>(); 1109 t.put(null, ClassFileConstants.JDK1_2); 1110 t.put(JavaCore.VERSION_1_2, ClassFileConstants.JDK1_2); 1111 t.put(JavaCore.VERSION_1_3, ClassFileConstants.JDK1_3); 1112 t.put(JavaCore.VERSION_1_4, ClassFileConstants.JDK1_4); 1113 t.put(JavaCore.VERSION_1_5, ClassFileConstants.JDK1_5); 1114 t.put(JavaCore.VERSION_1_6, ClassFileConstants.JDK1_6); 1115 t.put(JavaCore.VERSION_1_7, ClassFileConstants.JDK1_7); 1116 t.put(JavaCore.VERSION_1_8, ClassFileConstants.JDK1_8); 1117 t.put(JavaCore.VERSION_9, ClassFileConstants.JDK9); 1118 t.put(JavaCore.VERSION_10, ClassFileConstants.JDK10); 1119 t.put(JavaCore.VERSION_11, ClassFileConstants.JDK11); 1120 t.put(JavaCore.VERSION_12, ClassFileConstants.JDK12); 1121 t.put(JavaCore.VERSION_13, ClassFileConstants.JDK13); 1122 t.put(JavaCore.VERSION_14, ClassFileConstants.JDK14); 1123 return Collections.unmodifiableMap(t); 1124 } getApiLevelMapTable()1125 private static Map<String, Integer> getApiLevelMapTable() { 1126 Map<String, Integer> t = new HashMap<>(); 1127 t.put(null, JLS2_INTERNAL); 1128 t.put(JavaCore.VERSION_1_2, JLS2_INTERNAL); 1129 t.put(JavaCore.VERSION_1_3, JLS3_INTERNAL); 1130 t.put(JavaCore.VERSION_1_4, JLS4_INTERNAL); 1131 t.put(JavaCore.VERSION_1_5, JLS4_INTERNAL); 1132 t.put(JavaCore.VERSION_1_6, JLS4_INTERNAL); 1133 t.put(JavaCore.VERSION_1_7, JLS4_INTERNAL); 1134 t.put(JavaCore.VERSION_1_8, JLS8_INTERNAL); 1135 t.put(JavaCore.VERSION_9, JLS9_INTERNAL); 1136 t.put(JavaCore.VERSION_10, JLS10_INTERNAL); 1137 t.put(JavaCore.VERSION_11, JLS11_INTERNAL); 1138 t.put(JavaCore.VERSION_12, JLS12_INTERNAL); 1139 t.put(JavaCore.VERSION_13, JLS13_INTERNAL); 1140 t.put(JavaCore.VERSION_14, JLS14_INTERNAL); 1141 return Collections.unmodifiableMap(t); 1142 } 1143 /** 1144 * Return the API level supported by this AST. 1145 * 1146 * @return level the API level; one of the <code>JLS*</code> level constants 1147 * declared on <code>AST</code>; assume this set is open-ended 1148 * @since 3.0 1149 */ apiLevel()1150 public int apiLevel() { 1151 return this.apiLevel; 1152 } 1153 1154 /** 1155 * Creates an unparented node of the given node class 1156 * (non-abstract subclass of {@link ASTNode}). 1157 * 1158 * @param nodeClass AST node class 1159 * @return a new unparented node owned by this AST 1160 * @exception IllegalArgumentException if <code>nodeClass</code> is 1161 * <code>null</code> or is not a concrete node type class 1162 * or is not supported for this AST's API level 1163 * @since 3.0 1164 */ createInstance(Class nodeClass)1165 public ASTNode createInstance(Class nodeClass) { 1166 if (nodeClass == null) { 1167 throw new IllegalArgumentException(); 1168 } 1169 try { 1170 // invoke constructor with signature Foo(AST) 1171 Constructor c = nodeClass.getDeclaredConstructor(AST_CLASS); 1172 Object result = c.newInstance(this.THIS_AST); 1173 return (ASTNode) result; 1174 } catch (NoSuchMethodException | InstantiationException | IllegalAccessException e) { 1175 // all AST node classes have an accessible Foo(AST) constructor 1176 // therefore nodeClass is not legit 1177 throw new IllegalArgumentException(e); 1178 } catch (InvocationTargetException e) { 1179 // concrete AST node classes do not die in the constructor 1180 // therefore nodeClass is not legit 1181 throw new IllegalArgumentException(e.getCause()); 1182 } 1183 } 1184 1185 /** 1186 * Creates an unparented node of the given node type. 1187 * This convenience method is equivalent to: 1188 * <pre> 1189 * createInstance(ASTNode.nodeClassForType(nodeType)) 1190 * </pre> 1191 * 1192 * @param nodeType AST node type, one of the node type 1193 * constants declared on {@link ASTNode} 1194 * @return a new unparented node owned by this AST 1195 * @exception IllegalArgumentException if <code>nodeType</code> is 1196 * not a legal AST node type or if it's not supported for this AST's API level 1197 * @since 3.0 1198 */ createInstance(int nodeType)1199 public ASTNode createInstance(int nodeType) { 1200 // nodeClassForType throws IllegalArgumentException if nodeType is bogus 1201 Class nodeClass = ASTNode.nodeClassForType(nodeType); 1202 return createInstance(nodeClass); 1203 } 1204 1205 /** 1206 * Disable events. 1207 * This method is thread-safe for AST readers. 1208 * 1209 * @see #reenableEvents() 1210 * @since 3.0 1211 */ disableEvents()1212 final void disableEvents() { 1213 synchronized (this.internalASTLock) { 1214 // guard against concurrent access by another reader 1215 this.disableEvents++; 1216 } 1217 // while disableEvents > 0 no events will be reported, and mod count will stay fixed 1218 } 1219 1220 /** 1221 * Returns the binding resolver for this AST. 1222 * 1223 * @return the binding resolver for this AST 1224 */ getBindingResolver()1225 BindingResolver getBindingResolver() { 1226 return this.resolver; 1227 } 1228 1229 /** 1230 * Returns default node flags of new nodes of this AST. 1231 * 1232 * @return the default node flags of new nodes of this AST 1233 * @since 3.0 1234 */ getDefaultNodeFlag()1235 int getDefaultNodeFlag() { 1236 return this.defaultNodeFlag; 1237 } 1238 1239 /** 1240 * Returns the event handler for this AST. 1241 * 1242 * @return the event handler for this AST 1243 * @since 3.0 1244 */ getEventHandler()1245 NodeEventHandler getEventHandler() { 1246 return this.eventHandler; 1247 } 1248 1249 /** 1250 * Returns true if the ast tree was created with bindings recovery, false otherwise 1251 * 1252 * @return true if the ast tree was created with bindings recovery, false otherwise 1253 * @since 3.3 1254 */ hasBindingsRecovery()1255 public boolean hasBindingsRecovery() { 1256 return (this.bits & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0; 1257 } 1258 1259 /** 1260 * Returns true if the ast tree was created with bindings, false otherwise 1261 * 1262 * @return true if the ast tree was created with bindings, false otherwise 1263 * @since 3.3 1264 */ hasResolvedBindings()1265 public boolean hasResolvedBindings() { 1266 return (this.bits & RESOLVED_BINDINGS) != 0; 1267 } 1268 1269 /** 1270 * Returns true if the ast tree was created with statements recovery, false otherwise 1271 * 1272 * @return true if the ast tree was created with statements recovery, false otherwise 1273 * @since 3.3 1274 */ hasStatementsRecovery()1275 public boolean hasStatementsRecovery() { 1276 return (this.bits & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0; 1277 } 1278 1279 /* (omit javadoc for this method) 1280 * This method is a copy of setName(String[]) that doesn't do any validation. 1281 */ internalNewName(String[] identifiers)1282 Name internalNewName(String[] identifiers) { 1283 int count = identifiers.length; 1284 if (count == 0) { 1285 throw new IllegalArgumentException(); 1286 } 1287 final SimpleName simpleName = new SimpleName(this); 1288 simpleName.internalSetIdentifier(identifiers[0]); 1289 Name result = simpleName; 1290 for (int i = 1; i < count; i++) { 1291 SimpleName name = new SimpleName(this); 1292 name.internalSetIdentifier(identifiers[i]); 1293 result = newQualifiedName(result, name); 1294 } 1295 return result; 1296 } 1297 1298 /** 1299 * Returns the modification count for this AST. The modification count 1300 * is a non-negative value that increases (by 1 or perhaps by more) as 1301 * this AST or its nodes are changed. The initial value is unspecified. 1302 * <p> 1303 * The following things count as modifying an AST: 1304 * <ul> 1305 * <li>creating a new node owned by this AST,</li> 1306 * <li>adding a child to a node owned by this AST,</li> 1307 * <li>removing a child from a node owned by this AST,</li> 1308 * <li>setting a non-node attribute of a node owned by this AST.</li> 1309 * </ul> 1310 * <p> 1311 * Operations which do not entail creating or modifying existing nodes 1312 * do not increase the modification count. 1313 * </p> 1314 * <p> 1315 * N.B. This method may be called several times in the course 1316 * of a single client operation. The only promise is that the modification 1317 * count increases monotonically as the AST or its nodes change; there is 1318 * no promise that a modifying operation increases the count by exactly 1. 1319 * </p> 1320 * 1321 * @return the current value (non-negative) of the modification counter of 1322 * this AST 1323 */ modificationCount()1324 public long modificationCount() { 1325 return this.modificationCount; 1326 } 1327 1328 /** 1329 * Indicates that this AST is about to be modified. 1330 * <p> 1331 * The following things count as modifying an AST: 1332 * <ul> 1333 * <li>creating a new node owned by this AST</li> 1334 * <li>adding a child to a node owned by this AST</li> 1335 * <li>removing a child from a node owned by this AST</li> 1336 * <li>setting a non-node attribute of a node owned by this AST</li>. 1337 * </ul> 1338 * <p> 1339 * N.B. This method may be called several times in the course 1340 * of a single client operation. 1341 * </p> 1342 */ modifying()1343 void modifying() { 1344 // when this method is called during lazy init, events are disabled 1345 // and the modification count will not be increased 1346 if (this.disableEvents > 0) { 1347 return; 1348 } 1349 // increase the modification count 1350 this.modificationCount++; 1351 } 1352 1353 /** 1354 * A local method to workaround calling deprecated method in array type. 1355 * @deprecated 1356 */ setArrayComponentType(ArrayType arrayType, Type type)1357 private void setArrayComponentType(ArrayType arrayType, Type type) { 1358 arrayType.setComponentType(type); 1359 } 1360 1361 /** 1362 * Creates and returns a new unparented annotation type declaration 1363 * node for an unspecified, but legal, name; no modifiers; no javadoc; 1364 * and an empty list of member declarations. 1365 * 1366 * @return a new unparented annotation type declaration node 1367 * @exception UnsupportedOperationException if this operation is used in 1368 * a JLS2 AST 1369 * @since 3.1 1370 */ newAnnotationTypeDeclaration()1371 public AnnotationTypeDeclaration newAnnotationTypeDeclaration() { 1372 AnnotationTypeDeclaration result = new AnnotationTypeDeclaration(this); 1373 return result; 1374 } 1375 1376 /** 1377 * Creates and returns a new unparented annotation type 1378 * member declaration node for an unspecified, but legal, 1379 * member name and type; no modifiers; no javadoc; 1380 * and no default value. 1381 * 1382 * @return a new unparented annotation type member declaration node 1383 * @exception UnsupportedOperationException if this operation is used in 1384 * a JLS2 AST 1385 * @since 3.1 1386 */ newAnnotationTypeMemberDeclaration()1387 public AnnotationTypeMemberDeclaration newAnnotationTypeMemberDeclaration() { 1388 AnnotationTypeMemberDeclaration result = new AnnotationTypeMemberDeclaration(this); 1389 return result; 1390 } 1391 1392 /** 1393 * Creates and returns a new unparented anonymous class declaration 1394 * node owned by this AST. By default, the body declaration list is empty. 1395 * 1396 * @return a new unparented anonymous class declaration node 1397 */ newAnonymousClassDeclaration()1398 public AnonymousClassDeclaration newAnonymousClassDeclaration() { 1399 AnonymousClassDeclaration result = new AnonymousClassDeclaration(this); 1400 return result; 1401 } 1402 1403 /** 1404 * Creates and returns a new unparented array access expression node 1405 * owned by this AST. By default, the array and index expression are 1406 * both unspecified (but legal). 1407 * 1408 * @return a new unparented array access expression node 1409 */ newArrayAccess()1410 public ArrayAccess newArrayAccess() { 1411 ArrayAccess result = new ArrayAccess(this); 1412 return result; 1413 } 1414 1415 /** 1416 * Creates and returns a new unparented array creation expression node 1417 * owned by this AST. By default, the array type is an unspecified 1418 * 1-dimensional array, the list of dimensions is empty, and there is no 1419 * array initializer. 1420 * <p> 1421 * Examples: 1422 * <pre> 1423 * <code> 1424 * // new String[len] 1425 * ArrayCreation ac1 = ast.newArrayCreation(); 1426 * ac1.setType( 1427 * ast.newArrayType( 1428 * ast.newSimpleType(ast.newSimpleName("String")))); 1429 * ac1.dimensions().add(ast.newSimpleName("len")); 1430 * 1431 * // new double[7][24][] 1432 * ArrayCreation ac2 = ast.newArrayCreation(); 1433 * ac2.setType( 1434 * ast.newArrayType( 1435 * ast.newPrimitiveType(PrimitiveType.DOUBLE), 3)); 1436 * ac2.dimensions().add(ast.newNumberLiteral("7")); 1437 * ac2.dimensions().add(ast.newNumberLiteral("24")); 1438 * 1439 * // new int[] {1, 2} 1440 * ArrayCreation ac3 = ast.newArrayCreation(); 1441 * ac3.setType( 1442 * ast.newArrayType( 1443 * ast.newPrimitiveType(PrimitiveType.INT))); 1444 * ArrayInitializer ai = ast.newArrayInitializer(); 1445 * ac3.setInitializer(ai); 1446 * ai.expressions().add(ast.newNumberLiteral("1")); 1447 * ai.expressions().add(ast.newNumberLiteral("2")); 1448 * </code> 1449 * </pre> 1450 * 1451 * @return a new unparented array creation expression node 1452 */ newArrayCreation()1453 public ArrayCreation newArrayCreation() { 1454 ArrayCreation result = new ArrayCreation(this); 1455 return result; 1456 } 1457 1458 /** 1459 * Creates and returns a new unparented array initializer node 1460 * owned by this AST. By default, the initializer has no expressions. 1461 * 1462 * @return a new unparented array initializer node 1463 */ newArrayInitializer()1464 public ArrayInitializer newArrayInitializer() { 1465 ArrayInitializer result = new ArrayInitializer(this); 1466 return result; 1467 } 1468 1469 /** 1470 * Creates and returns a new unparented array type node with the given 1471 * element type, which cannot be an array type for API levels JLS8 and later. 1472 * By default, the array type has one non-annotated dimension. 1473 * <p> 1474 * For JLS4 and before, the given component type may be another array type. 1475 * </p> 1476 * 1477 * @param elementType element type for API level JLS8 and later, or the 1478 * component type (possibly another array type) for levels less than JLS8 1479 * @return a new unparented array type node 1480 * @exception IllegalArgumentException if: 1481 * <ul> 1482 * <li>the node belongs to a different AST</li> 1483 * <li>the node already has a parent</li> 1484 * <li>API level is JLS8 or later and type is an array type</li> 1485 * </ul> 1486 */ newArrayType(Type elementType)1487 public ArrayType newArrayType(Type elementType) { 1488 ArrayType result; 1489 if (this.apiLevel < JLS8_INTERNAL) { 1490 result = new ArrayType(this); 1491 setArrayComponentType(result, elementType); 1492 return result; 1493 } 1494 if (elementType.isArrayType()) { 1495 throw new IllegalArgumentException(); 1496 } 1497 result = new ArrayType(this); 1498 result.setElementType(elementType); 1499 return result; 1500 } 1501 1502 /** 1503 * Creates and returns a new unparented array type node with the given 1504 * element type and number of dimensions. 1505 * <p> 1506 * For JLS4 and before, the element type passed in can be an array type, but in that case, the 1507 * element type of the result will not be the same as what was passed in. 1508 * For JLS4 and before, the dimensions cannot be 0. 1509 * </p> 1510 * 1511 * @param elementType the element type (cannot be an array type for JLS8 and later) 1512 * @param dimensions the number of dimensions, a non-negative number 1513 * @return a new unparented array type node 1514 * @exception IllegalArgumentException if: 1515 * <ul> 1516 * <li>the node belongs to a different AST</li> 1517 * <li>the node already has a parent</li> 1518 * <li>the element type is null</li> 1519 * <li>the number of dimensions is lower than 0 (for JLS4 and before: lower than 1)</li> 1520 * <li>the number of dimensions is greater than 255</li> 1521 * <li>for levels from JLS8 and later, if the element type is an array type </li> 1522 * </ul> 1523 */ newArrayType(Type elementType, int dimensions)1524 public ArrayType newArrayType(Type elementType, int dimensions) { 1525 if (elementType == null) { 1526 throw new IllegalArgumentException(); 1527 } 1528 if (dimensions < 0 || dimensions > 255) { 1529 // max as per Java VM spec 1530 throw new IllegalArgumentException(); 1531 } 1532 ArrayType result; 1533 if (this.apiLevel < JLS8_INTERNAL) { 1534 if (dimensions < 1) { 1535 throw new IllegalArgumentException(); 1536 } 1537 result = new ArrayType(this); 1538 setArrayComponentType(result, elementType); 1539 for (int i = 2; i <= dimensions; i++) { 1540 result = newArrayType(result); 1541 } 1542 return result; 1543 } 1544 //level >= JLS8 1545 if (elementType.isArrayType()) { 1546 throw new IllegalArgumentException(); 1547 } 1548 result = new ArrayType(this, 0); 1549 result.setElementType(elementType); 1550 for (int i = 0; i < dimensions; ++i) { 1551 result.dimensions().add(new Dimension(this)); 1552 } 1553 return result; 1554 1555 } 1556 1557 /** 1558 * Creates a new unparented assert statement node owned by this AST. 1559 * By default, the first expression is unspecified, but legal, and has no 1560 * message expression. 1561 * 1562 * @return a new unparented assert statement node 1563 */ newAssertStatement()1564 public AssertStatement newAssertStatement() { 1565 return new AssertStatement(this); 1566 } 1567 1568 /** 1569 * Creates and returns a new unparented assignment expression node 1570 * owned by this AST. By default, the assignment operator is "=" and 1571 * the left and right hand side expressions are unspecified, but 1572 * legal, names. 1573 * 1574 * @return a new unparented assignment expression node 1575 */ newAssignment()1576 public Assignment newAssignment() { 1577 Assignment result = new Assignment(this); 1578 return result; 1579 } 1580 1581 /** 1582 * Creates an unparented block node owned by this AST, for an empty list 1583 * of statements. 1584 * 1585 * @return a new unparented, empty block node 1586 */ newBlock()1587 public Block newBlock() { 1588 return new Block(this); 1589 } 1590 1591 /** 1592 * Creates and returns a new block comment placeholder node. 1593 * <p> 1594 * Note that this node type is used to recording the source 1595 * range where a comment was found in the source string. 1596 * These comment nodes are normally found (only) in 1597 * {@linkplain CompilationUnit#getCommentList() 1598 * the comment table} for parsed compilation units. 1599 * </p> 1600 * 1601 * @return a new unparented block comment node 1602 * @since 3.0 1603 */ newBlockComment()1604 public BlockComment newBlockComment() { 1605 BlockComment result = new BlockComment(this); 1606 return result; 1607 } 1608 1609 /** 1610 * Creates and returns a new unparented boolean literal node. 1611 * <p> 1612 * For example, the assignment expression <code>foo = true</code> 1613 * is generated by the following snippet: 1614 * <pre> 1615 * <code> 1616 * Assignment e= ast.newAssignment(); 1617 * e.setLeftHandSide(ast.newSimpleName("foo")); 1618 * e.setRightHandSide(ast.newBooleanLiteral(true)); 1619 * </code> 1620 * </pre> 1621 * 1622 * @param value the boolean value 1623 * @return a new unparented boolean literal node 1624 */ newBooleanLiteral(boolean value)1625 public BooleanLiteral newBooleanLiteral(boolean value) { 1626 BooleanLiteral result = new BooleanLiteral(this); 1627 result.setBooleanValue(value); 1628 return result; 1629 } 1630 1631 /** 1632 * Creates an unparented break statement node owned by this AST. 1633 * The break statement has no label/identifier/expression and is not implicit. 1634 * 1635 * @return a new unparented break statement node 1636 */ newBreakStatement()1637 public BreakStatement newBreakStatement() { 1638 return new BreakStatement(this); 1639 } 1640 1641 /** 1642 * Creates and returns a new unparented cast expression node 1643 * owned by this AST. By default, the type and expression are unspecified 1644 * (but legal). 1645 * 1646 * @return a new unparented cast expression node 1647 */ newCastExpression()1648 public CastExpression newCastExpression() { 1649 CastExpression result = new CastExpression(this); 1650 return result; 1651 } 1652 1653 /** 1654 * Creates a new unparented catch clause node owned by this AST. 1655 * By default, the catch clause declares an unspecified, but legal, 1656 * exception declaration and has an empty block. 1657 * 1658 * @return a new unparented catch clause node 1659 */ newCatchClause()1660 public CatchClause newCatchClause() { 1661 return new CatchClause(this); 1662 } 1663 1664 /** 1665 * Creates and returns a new unparented character literal node. 1666 * Initially the node has an unspecified character literal. 1667 * 1668 * @return a new unparented character literal node 1669 */ newCharacterLiteral()1670 public CharacterLiteral newCharacterLiteral() { 1671 return new CharacterLiteral(this); 1672 } 1673 1674 /** 1675 * Creates and returns a new unparented class instance creation 1676 * ("new") expression node owned by this AST. By default, 1677 * there is no qualifying expression, no type parameters, 1678 * an unspecified (but legal) type name, an empty list of 1679 * arguments, and does not declare an anonymous class declaration. 1680 * 1681 * @return a new unparented class instance creation expression node 1682 */ newClassInstanceCreation()1683 public ClassInstanceCreation newClassInstanceCreation() { 1684 ClassInstanceCreation result = new ClassInstanceCreation(this); 1685 return result; 1686 } 1687 1688 //=============================== DECLARATIONS =========================== 1689 /** 1690 * Creates an unparented compilation unit node owned by this AST. 1691 * The compilation unit initially has no package declaration, no 1692 * import declarations, and no type declarations. 1693 * 1694 * @return the new unparented compilation unit node 1695 */ newCompilationUnit()1696 public CompilationUnit newCompilationUnit() { 1697 return new CompilationUnit(this); 1698 } 1699 1700 /** 1701 * Creates and returns a new unparented conditional expression node 1702 * owned by this AST. By default, the condition and both expressions 1703 * are unspecified (but legal). 1704 * 1705 * @return a new unparented array conditional expression node 1706 */ newConditionalExpression()1707 public ConditionalExpression newConditionalExpression() { 1708 ConditionalExpression result = new ConditionalExpression(this); 1709 return result; 1710 } 1711 1712 /** 1713 * Creates an unparented alternate constructor ("this(...);") invocation 1714 * statement node owned by this AST. By default, the lists of arguments 1715 * and type arguments are both empty. 1716 * <p> 1717 * Note that this type of node is a Statement, whereas a regular 1718 * method invocation is an Expression. The only valid use of these 1719 * statements are as the first statement of a constructor body. 1720 * </p> 1721 * 1722 * @return a new unparented alternate constructor invocation statement node 1723 */ newConstructorInvocation()1724 public ConstructorInvocation newConstructorInvocation() { 1725 ConstructorInvocation result = new ConstructorInvocation(this); 1726 return result; 1727 } 1728 1729 /** 1730 * Creates an unparented continue statement node owned by this AST. 1731 * The continue statement has no label. 1732 * 1733 * @return a new unparented continue statement node 1734 */ newContinueStatement()1735 public ContinueStatement newContinueStatement() { 1736 return new ContinueStatement(this); 1737 } 1738 1739 /** 1740 * Creates an unparented creation reference node owned by this AST. 1741 * By default, the type is unspecified (but legal), and there are no type arguments. 1742 * 1743 * @return a new unparented creation reference expression node 1744 * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST 1745 * @since 3.10 1746 */ newCreationReference()1747 public CreationReference newCreationReference() { 1748 CreationReference result = new CreationReference(this); 1749 return result; 1750 } 1751 1752 /** 1753 * Creates a new unparented do statement node owned by this AST. 1754 * By default, the expression is unspecified (but legal), and 1755 * the body statement is an empty block. 1756 * 1757 * @return a new unparented do statement node 1758 */ newDoStatement()1759 public DoStatement newDoStatement() { 1760 return new DoStatement(this); 1761 } 1762 1763 /** 1764 * Creates a new unparented empty statement node owned by this AST. 1765 * 1766 * @return a new unparented empty statement node 1767 */ newEmptyStatement()1768 public EmptyStatement newEmptyStatement() { 1769 return new EmptyStatement(this); 1770 } 1771 1772 /** 1773 * Creates a new unparented enhanced for statement node owned by this AST. 1774 * By default, the paramter and expression are unspecified 1775 * but legal subtrees, and the body is an empty block. 1776 * 1777 * @return a new unparented throw statement node 1778 * @exception UnsupportedOperationException if this operation is used in 1779 * a JLS2 AST 1780 * @since 3.1 1781 */ newEnhancedForStatement()1782 public EnhancedForStatement newEnhancedForStatement() { 1783 return new EnhancedForStatement(this); 1784 } 1785 1786 /** 1787 * Creates an unparented enum constant declaration node owned by this AST. 1788 * The name of the constant is an unspecified, but legal, name; 1789 * no doc comment; no modifiers or annotations; no arguments; 1790 * and does not declare an anonymous class. 1791 * 1792 * @return a new unparented enum constant declaration node 1793 * @exception UnsupportedOperationException if this operation is used in 1794 * a JLS2 AST 1795 * @since 3.1 1796 */ newEnumConstantDeclaration()1797 public EnumConstantDeclaration newEnumConstantDeclaration() { 1798 EnumConstantDeclaration result = new EnumConstantDeclaration(this); 1799 return result; 1800 } 1801 1802 /** 1803 * Creates an unparented enum declaration node owned by this AST. 1804 * The name of the enum is an unspecified, but legal, name; 1805 * no doc comment; no modifiers or annotations; 1806 * no superinterfaces; and empty lists of enum constants 1807 * and body declarations. 1808 * 1809 * @return a new unparented enum declaration node 1810 * @exception UnsupportedOperationException if this operation is used in 1811 * a JLS2 AST 1812 * @since 3.1 1813 */ newEnumDeclaration()1814 public EnumDeclaration newEnumDeclaration() { 1815 EnumDeclaration result = new EnumDeclaration(this); 1816 return result; 1817 } 1818 1819 /** 1820 * Creates and returns a new unparented exports directive 1821 * node for an unspecified, but legal, name; no target modules 1822 * 1823 * @return a new unparented exports directive node 1824 * @exception UnsupportedOperationException if this operation is used in an AST with level less than JLS9 1825 * @since 3.14 1826 */ newExportsStatement()1827 public ExportsDirective newExportsStatement() { 1828 ExportsDirective result = new ExportsDirective(this); 1829 return result; 1830 } 1831 1832 /** 1833 * Creates an unparented expression method reference node owned by this AST. 1834 * By default, the expression and method name are unspecified (but legal), 1835 * and there are no type arguments. 1836 * 1837 * @return a new unparented expression method reference expression node 1838 * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST 1839 * @since 3.10 1840 */ newExpressionMethodReference()1841 public ExpressionMethodReference newExpressionMethodReference() { 1842 ExpressionMethodReference result = new ExpressionMethodReference(this); 1843 return result; 1844 } 1845 1846 /** 1847 * Creates a new unparented expression statement node owned by this AST, 1848 * for the given expression. 1849 * <p> 1850 * This method can be used to convert an expression 1851 * (<code>Expression</code>) into a statement (<code>Type</code>) 1852 * by wrapping it. Note, however, that the result is only legal for 1853 * limited expression types, including method invocations, assignments, 1854 * and increment/decrement operations. 1855 * </p> 1856 * 1857 * @param expression the expression 1858 * @return a new unparented statement node 1859 * @exception IllegalArgumentException if: 1860 * <ul> 1861 * <li>the node belongs to a different AST</li> 1862 * <li>the node already has a parent</li> 1863 * </ul> 1864 */ newExpressionStatement(Expression expression)1865 public ExpressionStatement newExpressionStatement(Expression expression) { 1866 ExpressionStatement result = new ExpressionStatement(this); 1867 result.setExpression(expression); 1868 return result; 1869 } 1870 1871 /** 1872 * Creates and returns a new unparented annotatable dimension node 1873 * (Supported only in JLS8 level). 1874 * 1875 * @return a new unparented annotatable dimension node 1876 * @exception IllegalArgumentException if: 1877 * <ul> 1878 * <li>the node belongs to a different AST</li> 1879 * <li>the node already has a parent</li> 1880 * </ul> 1881 * @exception UnsupportedOperationException if this operation is used 1882 * in a JLS2, JLS3 or JLS4 AST 1883 * @since 3.10 1884 */ newDimension()1885 public Dimension newDimension() { 1886 Dimension result = new Dimension(this); 1887 return result; 1888 } 1889 1890 /** 1891 * Creates and returns a new unparented field access expression node 1892 * owned by this AST. By default, the expression and field are both 1893 * unspecified, but legal, names. 1894 * 1895 * @return a new unparented field access expression node 1896 */ newFieldAccess()1897 public FieldAccess newFieldAccess() { 1898 FieldAccess result = new FieldAccess(this); 1899 return result; 1900 } 1901 1902 /** 1903 * Creates a new unparented field declaration node owned by this AST, 1904 * for the given variable declaration fragment. By default, there are no 1905 * modifiers, no doc comment, and the base type is unspecified 1906 * (but legal). 1907 * <p> 1908 * This method can be used to wrap a variable declaration fragment 1909 * (<code>VariableDeclarationFragment</code>) into a field declaration 1910 * suitable for inclusion in the body of a type declaration 1911 * (<code>FieldDeclaration</code> implements <code>BodyDeclaration</code>). 1912 * Additional variable declaration fragments can be added afterwards. 1913 * </p> 1914 * 1915 * @param fragment the variable declaration fragment 1916 * @return a new unparented field declaration node 1917 * @exception IllegalArgumentException if: 1918 * <ul> 1919 * <li>the node belongs to a different AST</li> 1920 * <li>the node already has a parent</li> 1921 * <li>the given fragment is null</li> 1922 * </ul> 1923 */ newFieldDeclaration(VariableDeclarationFragment fragment)1924 public FieldDeclaration newFieldDeclaration(VariableDeclarationFragment fragment) { 1925 if (fragment == null) { 1926 throw new IllegalArgumentException(); 1927 } 1928 FieldDeclaration result = new FieldDeclaration(this); 1929 result.fragments().add(fragment); 1930 return result; 1931 } 1932 1933 /** 1934 * Creates a new unparented for statement node owned by this AST. 1935 * By default, there are no initializers, no condition expression, 1936 * no updaters, and the body is an empty block. 1937 * 1938 * @return a new unparented for statement node 1939 */ newForStatement()1940 public ForStatement newForStatement() { 1941 return new ForStatement(this); 1942 } 1943 1944 /** 1945 * Creates a new unparented if statement node owned by this AST. 1946 * By default, the expression is unspecified (but legal), 1947 * the then statement is an empty block, and there is no else statement. 1948 * 1949 * @return a new unparented if statement node 1950 */ newIfStatement()1951 public IfStatement newIfStatement() { 1952 return new IfStatement(this); 1953 } 1954 1955 /** 1956 * Creates an unparented import declaration node owned by this AST. 1957 * The import declaration initially contains a single-type import 1958 * of a type with an unspecified name. 1959 * 1960 * @return the new unparented import declaration node 1961 */ newImportDeclaration()1962 public ImportDeclaration newImportDeclaration() { 1963 ImportDeclaration result = new ImportDeclaration(this); 1964 return result; 1965 } 1966 1967 /** 1968 * Creates and returns a new unparented infix expression node 1969 * owned by this AST. By default, the operator and left and right 1970 * operand are unspecified (but legal), and there are no extended 1971 * operands. 1972 * 1973 * @return a new unparented infix expression node 1974 */ newInfixExpression()1975 public InfixExpression newInfixExpression() { 1976 InfixExpression result = new InfixExpression(this); 1977 return result; 1978 } 1979 1980 /** 1981 * Creates an unparented initializer node owned by this AST, with an 1982 * empty block. By default, the initializer has no modifiers and 1983 * an empty block. 1984 * 1985 * @return a new unparented initializer node 1986 */ newInitializer()1987 public Initializer newInitializer() { 1988 Initializer result = new Initializer(this); 1989 return result; 1990 } 1991 1992 /** 1993 * Creates and returns a new unparented instanceof expression node 1994 * owned by this AST. By default, the operator and left and right 1995 * operand are unspecified (but legal). 1996 * 1997 * @return a new unparented instanceof expression node 1998 */ newInstanceofExpression()1999 public InstanceofExpression newInstanceofExpression() { 2000 InstanceofExpression result = new InstanceofExpression(this); 2001 return result; 2002 } 2003 2004 /** 2005 * Creates and returns a new doc comment node. 2006 * Initially the new node has an empty list of tag elements 2007 * (and, for backwards compatability, an unspecified, but legal, 2008 * doc comment string) 2009 * 2010 * @return a new unparented doc comment node 2011 */ newJavadoc()2012 public Javadoc newJavadoc() { 2013 Javadoc result = new Javadoc(this); 2014 return result; 2015 } 2016 2017 /** 2018 * Creates a new unparented labeled statement node owned by this AST. 2019 * By default, the label and statement are both unspecified, but legal. 2020 * 2021 * @return a new unparented labeled statement node 2022 */ newLabeledStatement()2023 public LabeledStatement newLabeledStatement() { 2024 return new LabeledStatement(this); 2025 } 2026 2027 /** 2028 * Creates an unparented lambda expression node owned by this AST. 2029 * By default, the new lambda expression has parentheses enabled, contains an empty argument 2030 * list, and the body is an empty block. 2031 * 2032 * @return a new unparented lambda expression node 2033 * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST 2034 * @since 3.10 2035 */ newLambdaExpression()2036 public LambdaExpression newLambdaExpression() { 2037 LambdaExpression result = new LambdaExpression(this); 2038 return result; 2039 } 2040 2041 /** 2042 * Creates and returns a new line comment placeholder node. 2043 * <p> 2044 * Note that this node type is used to recording the source 2045 * range where a comment was found in the source string. 2046 * These comment nodes are normally found (only) in 2047 * {@linkplain CompilationUnit#getCommentList() 2048 * the comment table} for parsed compilation units. 2049 * </p> 2050 * 2051 * @return a new unparented line comment node 2052 * @since 3.0 2053 */ newLineComment()2054 public LineComment newLineComment() { 2055 LineComment result = new LineComment(this); 2056 return result; 2057 } 2058 2059 /** 2060 * Creates and returns a new unparented marker annotation node with 2061 * an unspecified type name. 2062 * 2063 * @return a new unparented marker annotation node 2064 * @exception UnsupportedOperationException if this operation is used in 2065 * a JLS2 AST 2066 * @since 3.1 2067 */ newMarkerAnnotation()2068 public MarkerAnnotation newMarkerAnnotation() { 2069 MarkerAnnotation result = new MarkerAnnotation(this); 2070 return result; 2071 } 2072 2073 /** 2074 * Creates and returns a new member reference node. 2075 * Initially the new node has no qualifier name and 2076 * an unspecified, but legal, member name. 2077 * <p> 2078 * Note that this node type is used only inside doc comments 2079 * ({@link Javadoc}). 2080 * </p> 2081 * 2082 * @return a new unparented member reference node 2083 * @since 3.0 2084 */ newMemberRef()2085 public MemberRef newMemberRef() { 2086 MemberRef result = new MemberRef(this); 2087 return result; 2088 } 2089 2090 //=============================== COMMENTS =========================== 2091 2092 /** 2093 * Creates and returns a new unparented member value pair node with 2094 * an unspecified member name and value. 2095 * 2096 * @return a new unparented member value pair node 2097 * @exception UnsupportedOperationException if this operation is used in 2098 * a JLS2 AST 2099 * @since 3.1 2100 */ newMemberValuePair()2101 public MemberValuePair newMemberValuePair() { 2102 MemberValuePair result = new MemberValuePair(this); 2103 return result; 2104 } 2105 2106 /** 2107 * Creates an unparented method declaration node owned by this AST. 2108 * By default, the declaration is for a method of an unspecified, but 2109 * legal, name; no modifiers; no doc comment; no parameters; return 2110 * type void; no extra array dimensions; no thrown exceptions; and no 2111 * body (as opposed to an empty body). 2112 * <p> 2113 * To create a constructor, use this method and then call 2114 * <code>MethodDeclaration.setConstructor(true)</code> and 2115 * <code>MethodDeclaration.setName(className)</code>. 2116 * </p> 2117 * 2118 * @return a new unparented method declaration node 2119 */ newMethodDeclaration()2120 public MethodDeclaration newMethodDeclaration() { 2121 MethodDeclaration result = new MethodDeclaration(this); 2122 result.setConstructor(false); 2123 return result; 2124 } 2125 2126 /** 2127 * Creates an unparented method invocation expression node owned by this 2128 * AST. By default, the name of the method is unspecified (but legal) 2129 * there is no receiver expression, no type arguments, and the list of 2130 * arguments is empty. 2131 * 2132 * @return a new unparented method invocation expression node 2133 */ newMethodInvocation()2134 public MethodInvocation newMethodInvocation() { 2135 MethodInvocation result = new MethodInvocation(this); 2136 return result; 2137 } 2138 2139 /** 2140 * Creates and returns a new method reference node. 2141 * Initially the new node has no qualifier name, 2142 * an unspecified, but legal, method name, and an 2143 * empty parameter list. 2144 * <p> 2145 * Note that this node type is used only inside doc comments 2146 * ({@link Javadoc Javadoc}). 2147 * </p> 2148 * 2149 * @return a new unparented method reference node 2150 * @since 3.0 2151 */ newMethodRef()2152 public MethodRef newMethodRef() { 2153 MethodRef result = new MethodRef(this); 2154 return result; 2155 } 2156 2157 /** 2158 * Creates and returns a new method reference node. 2159 * Initially the new node has an unspecified, but legal, 2160 * type, not variable arity, and no parameter name. 2161 * <p> 2162 * Note that this node type is used only inside doc comments 2163 * ({@link Javadoc}). 2164 * </p> 2165 * 2166 * @return a new unparented method reference parameter node 2167 * @since 3.0 2168 */ newMethodRefParameter()2169 public MethodRefParameter newMethodRefParameter() { 2170 MethodRefParameter result = new MethodRefParameter(this); 2171 return result; 2172 } 2173 2174 /** 2175 * Creates and returns a new unparented modifier node for the given 2176 * modifier. 2177 * 2178 * @param keyword one of the modifier keyword constants 2179 * @return a new unparented modifier node 2180 * @exception IllegalArgumentException if the primitive type code is invalid 2181 * @exception UnsupportedOperationException if this operation is used in 2182 * a JLS2 AST 2183 * @since 3.1 2184 */ newModifier(Modifier.ModifierKeyword keyword)2185 public Modifier newModifier(Modifier.ModifierKeyword keyword) { 2186 Modifier result = new Modifier(this); 2187 result.setKeyword(keyword); 2188 return result; 2189 } 2190 2191 /** 2192 * Creates and returns a new unparented module modifier node for the given 2193 * module modifier. 2194 * 2195 * @param keyword one of the module modifier keyword constants 2196 * @return a new unparented module modifier node 2197 * @exception IllegalArgumentException if the primitive type code is invalid 2198 * @exception UnsupportedOperationException if this operation is used in 2199 * an AST with level less than JLS9 2200 * @since 3.14 2201 */ newModuleModifier(ModuleModifier.ModuleModifierKeyword keyword)2202 public ModuleModifier newModuleModifier(ModuleModifier.ModuleModifierKeyword keyword) { 2203 ModuleModifier result = new ModuleModifier(this); 2204 result.setKeyword(keyword); 2205 return result; 2206 } 2207 2208 /** 2209 * Creates and returns a list of new unparented modifier nodes 2210 * for the given modifier flags. When multiple modifiers are 2211 * requested, the modifier nodes will appear in the following order: 2212 * <pre> public protected private 2213 * abstract default static final synchronized native strictfp transient volatile</pre> 2214 * <p> 2215 * This order is consistent with the recommendations in JLS8 ("*Modifier:" rules in chapters 8 and 9). 2216 * </p> 2217 * 2218 * @param flags bitwise or of modifier flags declared on {@link Modifier} 2219 * @return a possibly empty list of new unparented modifier nodes 2220 * (element type <code>Modifier</code>) 2221 * @exception UnsupportedOperationException if this operation is used in 2222 * a JLS2 AST 2223 * @since 3.1 2224 */ newModifiers(int flags)2225 public List newModifiers(int flags) { 2226 if (this.apiLevel == AST.JLS2) { 2227 unsupportedIn2(); 2228 } 2229 List result = new ArrayList(3); // 3 modifiers is more than average 2230 if (Modifier.isPublic(flags)) { 2231 result.add(newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); 2232 } 2233 if (Modifier.isProtected(flags)) { 2234 result.add(newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD)); 2235 } 2236 if (Modifier.isPrivate(flags)) { 2237 result.add(newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD)); 2238 } 2239 if (Modifier.isAbstract(flags)) { 2240 result.add(newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD)); 2241 } 2242 if (Modifier.isDefault(flags)) { 2243 result.add(newModifier(Modifier.ModifierKeyword.DEFAULT_KEYWORD)); 2244 } 2245 if (Modifier.isStatic(flags)) { 2246 result.add(newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD)); 2247 } 2248 if (Modifier.isFinal(flags)) { 2249 result.add(newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD)); 2250 } 2251 if (Modifier.isSynchronized(flags)) { 2252 result.add(newModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD)); 2253 } 2254 if (Modifier.isNative(flags)) { 2255 result.add(newModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD)); 2256 } 2257 if (Modifier.isStrictfp(flags)) { 2258 result.add(newModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD)); 2259 } 2260 if (Modifier.isTransient(flags)) { 2261 result.add(newModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD)); 2262 } 2263 if (Modifier.isVolatile(flags)) { 2264 result.add(newModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD)); 2265 } 2266 return result; 2267 } 2268 2269 /** 2270 * Creates and returns a new unparented module declaration 2271 * node for an unspecified, but legal, name; no modifiers; no javadoc; 2272 * and an empty list of statements. 2273 * 2274 * @return a new unparented module declaration node 2275 * @exception UnsupportedOperationException if this operation is used in an AST with level less than JLS9 2276 * @since 3.14 2277 */ newModuleDeclaration()2278 public ModuleDeclaration newModuleDeclaration() { 2279 ModuleDeclaration result = new ModuleDeclaration(this); 2280 return result; 2281 } 2282 2283 /** 2284 * Creates and returns a new unparented name node for the given name. 2285 * The name string must consist of 1 or more name segments separated 2286 * by single dots '.'. Returns a {@link QualifiedName} if the name has 2287 * dots, and a {@link SimpleName} otherwise. Each of the name 2288 * segments should be legal Java identifiers (this constraint may or may 2289 * not be enforced), and there must be at least one name segment. 2290 * The string must not contains white space, '<', '>', 2291 * '[', ']', or other any other characters that are not 2292 * part of the Java identifiers or separating '.'s. 2293 * 2294 * @param qualifiedName string consisting of 1 or more name segments, 2295 * each of which is a legal Java identifier, separated by single dots '.' 2296 * @return a new unparented name node 2297 * @exception IllegalArgumentException if: 2298 * <ul> 2299 * <li>the string is empty</li> 2300 * <li>the string begins or ends in a '.'</li> 2301 * <li>the string has adjacent '.'s</li> 2302 * <li>the segments between the '.'s are not valid Java identifiers</li> 2303 * </ul> 2304 * @since 3.1 2305 */ newName(String qualifiedName)2306 public Name newName(String qualifiedName) { 2307 StringTokenizer t = new StringTokenizer(qualifiedName, ".", true); //$NON-NLS-1$ 2308 Name result = null; 2309 // balance is # of name tokens - # of period tokens seen so far 2310 // initially 0; finally 1; should never drop < 0 or > 1 2311 int balance = 0; 2312 while(t.hasMoreTokens()) { 2313 String s = t.nextToken(); 2314 if (s.indexOf('.') >= 0) { 2315 // this is a delimiter 2316 if (s.length() > 1) { 2317 // too many dots in a row 2318 throw new IllegalArgumentException(); 2319 } 2320 balance--; 2321 if (balance < 0) { 2322 throw new IllegalArgumentException(); 2323 } 2324 } else { 2325 // this is an identifier segment 2326 balance++; 2327 SimpleName name = newSimpleName(s); 2328 if (result == null) { 2329 result = name; 2330 } else { 2331 result = newQualifiedName(result, name); 2332 } 2333 } 2334 } 2335 if (balance != 1) { 2336 throw new IllegalArgumentException(); 2337 } 2338 return result; 2339 } 2340 2341 /** 2342 * Creates and returns a new unparented name node for the given name 2343 * segments. Returns a simple name if there is only one name segment, and 2344 * a qualified name if there are multiple name segments. Each of the name 2345 * segments should be legal Java identifiers (this constraint may or may 2346 * not be enforced), and there must be at least one name segment. 2347 * 2348 * @param identifiers a list of 1 or more name segments, each of which 2349 * is a legal Java identifier 2350 * @return a new unparented name node 2351 * @exception IllegalArgumentException if: 2352 * <ul> 2353 * <li>the identifier is invalid</li> 2354 * <li>the list of identifiers is empty</li> 2355 * </ul> 2356 */ newName(String[] identifiers)2357 public Name newName(String[] identifiers) { 2358 // update internalSetName(String[] if changed 2359 int count = identifiers.length; 2360 if (count == 0) { 2361 throw new IllegalArgumentException(); 2362 } 2363 Name result = newSimpleName(identifiers[0]); 2364 for (int i = 1; i < count; i++) { 2365 SimpleName name = newSimpleName(identifiers[i]); 2366 result = newQualifiedName(result, name); 2367 } 2368 return result; 2369 } 2370 2371 /** 2372 * Creates and returns a new unparented name qualified type node with 2373 * the given qualifier and name. 2374 * 2375 * @param qualifier the name qualifier name node 2376 * @param name the simple name being qualified 2377 * @return a new unparented qualified type node 2378 * @exception IllegalArgumentException if: 2379 * <ul> 2380 * <li>the node belongs to a different AST</li> 2381 * <li>the node already has a parent</li> 2382 * </ul> 2383 * @exception UnsupportedOperationException if this operation is used in 2384 * a JLS2, JLS3 and JLS4 AST 2385 * @since 3.10 2386 */ newNameQualifiedType(Name qualifier, SimpleName name)2387 public NameQualifiedType newNameQualifiedType(Name qualifier, SimpleName name) { 2388 NameQualifiedType result = new NameQualifiedType(this); 2389 result.setQualifier(qualifier); 2390 result.setName(name); 2391 return result; 2392 } 2393 2394 /** 2395 * Creates and returns a new unparented normal annotation node with 2396 * an unspecified type name and an empty list of member value 2397 * pairs. 2398 * 2399 * @return a new unparented normal annotation node 2400 * @exception UnsupportedOperationException if this operation is used in 2401 * a JLS2 AST 2402 * @since 3.1 2403 */ newNormalAnnotation()2404 public NormalAnnotation newNormalAnnotation() { 2405 NormalAnnotation result = new NormalAnnotation(this); 2406 return result; 2407 } 2408 2409 /** 2410 * Creates and returns a new unparented null literal node. 2411 * 2412 * @return a new unparented null literal node 2413 */ newNullLiteral()2414 public NullLiteral newNullLiteral() { 2415 return new NullLiteral(this); 2416 } 2417 2418 /** 2419 * Creates and returns a new unparented number literal node. 2420 * Initially the number literal token is <code>"0"</code>. 2421 * 2422 * @return a new unparented number literal node 2423 */ newNumberLiteral()2424 public NumberLiteral newNumberLiteral() { 2425 NumberLiteral result = new NumberLiteral(this); 2426 return result; 2427 } 2428 2429 /** 2430 * Creates and returns a new unparented number literal node. 2431 * 2432 * @param literal the token for the numeric literal as it would 2433 * appear in Java source code 2434 * @return a new unparented number literal node 2435 * @exception IllegalArgumentException if the literal is null 2436 */ newNumberLiteral(String literal)2437 public NumberLiteral newNumberLiteral(String literal) { 2438 if (literal == null) { 2439 throw new IllegalArgumentException(); 2440 } 2441 NumberLiteral result = new NumberLiteral(this); 2442 result.setToken(literal); 2443 return result; 2444 } 2445 2446 /** 2447 * Creates and returns a new unparented opens directive 2448 * node for an unspecified, but legal, name; no target modules 2449 * 2450 * @return a new unparented opens directive node 2451 * @exception UnsupportedOperationException if this operation is used in an AST with level less than JLS9 2452 * @since 3.14 2453 */ newOpensDirective()2454 public OpensDirective newOpensDirective() { 2455 OpensDirective result = new OpensDirective(this); 2456 return result; 2457 } 2458 2459 /** 2460 * Creates an unparented package declaration node owned by this AST. 2461 * The package declaration initially declares a package with an 2462 * unspecified name. 2463 * 2464 * @return the new unparented package declaration node 2465 */ newPackageDeclaration()2466 public PackageDeclaration newPackageDeclaration() { 2467 PackageDeclaration result = new PackageDeclaration(this); 2468 return result; 2469 } 2470 2471 /** 2472 * Creates and returns a new unparented parameterized type node with the 2473 * given type and an empty list of type arguments. 2474 * 2475 * @param type the type that is parameterized 2476 * @return a new unparented parameterized type node 2477 * @exception IllegalArgumentException if: 2478 * <ul> 2479 * <li>the node belongs to a different AST</li> 2480 * <li>the node already has a parent</li> 2481 * </ul> 2482 * @exception UnsupportedOperationException if this operation is used in 2483 * a JLS2 AST 2484 * @since 3.1 2485 */ newParameterizedType(Type type)2486 public ParameterizedType newParameterizedType(Type type) { 2487 ParameterizedType result = new ParameterizedType(this); 2488 result.setType(type); 2489 return result; 2490 } 2491 2492 /** 2493 * Creates and returns a new unparented parenthesized expression node 2494 * owned by this AST. By default, the expression is unspecified (but legal). 2495 * 2496 * @return a new unparented parenthesized expression node 2497 */ newParenthesizedExpression()2498 public ParenthesizedExpression newParenthesizedExpression() { 2499 ParenthesizedExpression result = new ParenthesizedExpression(this); 2500 return result; 2501 } 2502 2503 /** 2504 * Creates and returns a new unparented postfix expression node 2505 * owned by this AST. By default, the operator and operand are 2506 * unspecified (but legal). 2507 * 2508 * @return a new unparented postfix expression node 2509 */ newPostfixExpression()2510 public PostfixExpression newPostfixExpression() { 2511 PostfixExpression result = new PostfixExpression(this); 2512 return result; 2513 } 2514 2515 /** 2516 * Creates and returns a new unparented prefix expression node 2517 * owned by this AST. By default, the operator and operand are 2518 * unspecified (but legal). 2519 * 2520 * @return a new unparented prefix expression node 2521 */ newPrefixExpression()2522 public PrefixExpression newPrefixExpression() { 2523 PrefixExpression result = new PrefixExpression(this); 2524 return result; 2525 } 2526 2527 /** 2528 * Creates and returns a new unparented primitive type node with the given 2529 * type code. 2530 * 2531 * @param typeCode one of the primitive type code constants declared in 2532 * <code>PrimitiveType</code> 2533 * @return a new unparented primitive type node 2534 * @exception IllegalArgumentException if the primitive type code is invalid 2535 */ newPrimitiveType(PrimitiveType.Code typeCode)2536 public PrimitiveType newPrimitiveType(PrimitiveType.Code typeCode) { 2537 PrimitiveType result = new PrimitiveType(this); 2538 result.setPrimitiveTypeCode(typeCode); 2539 return result; 2540 } 2541 2542 /** 2543 * Creates and returns a new unparented provides directive 2544 * node for an unspecified, but legal, type; no target types 2545 * 2546 * @return a new unparented provides directive node 2547 * @exception UnsupportedOperationException if this operation is used in an AST with level less than JLS9 2548 * @since 3.14 2549 */ newProvidesDirective()2550 public ProvidesDirective newProvidesDirective() { 2551 ProvidesDirective result = new ProvidesDirective(this); 2552 return result; 2553 } 2554 2555 /** 2556 * Creates and returns a new unparented qualified name node for the given 2557 * qualifier and simple name child node. 2558 * 2559 * @param qualifier the qualifier name node 2560 * @param name the simple name being qualified 2561 * @return a new unparented qualified name node 2562 * @exception IllegalArgumentException if: 2563 * <ul> 2564 * <li>the node belongs to a different AST</li> 2565 * <li>the node already has a parent</li> 2566 * </ul> 2567 */ newQualifiedName( Name qualifier, SimpleName name)2568 public QualifiedName newQualifiedName( 2569 Name qualifier, 2570 SimpleName name) { 2571 QualifiedName result = new QualifiedName(this); 2572 result.setQualifier(qualifier); 2573 result.setName(name); 2574 return result; 2575 2576 } 2577 2578 /** 2579 * Creates and returns a new unparented qualified type node with 2580 * the given qualifier type and name. 2581 * 2582 * @param qualifier the qualifier type node 2583 * @param name the simple name being qualified 2584 * @return a new unparented qualified type node 2585 * @exception IllegalArgumentException if: 2586 * <ul> 2587 * <li>the node belongs to a different AST</li> 2588 * <li>the node already has a parent</li> 2589 * </ul> 2590 * @exception UnsupportedOperationException if this operation is used in 2591 * a JLS2 AST 2592 * @since 3.1 2593 */ newQualifiedType(Type qualifier, SimpleName name)2594 public QualifiedType newQualifiedType(Type qualifier, SimpleName name) { 2595 QualifiedType result = new QualifiedType(this); 2596 result.setQualifier(qualifier); 2597 result.setName(name); 2598 return result; 2599 } 2600 2601 /** 2602 * Creates and returns a new unparented requires directive 2603 * node for an unspecified, but legal, name; 2604 * 2605 * @return a new unparented requires directive node 2606 * @exception UnsupportedOperationException if this operation is used in an AST with level less than JLS9 2607 * @since 3.14 2608 */ newRequiresDirective()2609 public RequiresDirective newRequiresDirective() { 2610 RequiresDirective result = new RequiresDirective(this); 2611 return result; 2612 } 2613 2614 /** 2615 * Creates a new unparented return statement node owned by this AST. 2616 * By default, the return statement has no expression. 2617 * 2618 * @return a new unparented return statement node 2619 */ newReturnStatement()2620 public ReturnStatement newReturnStatement() { 2621 return new ReturnStatement(this); 2622 } 2623 2624 //=============================== NAMES =========================== 2625 /** 2626 * Creates and returns a new unparented simple name node for the given 2627 * identifier. The identifier should be a legal Java identifier, but not 2628 * a keyword, boolean literal ("true", "false") or null literal ("null"). 2629 * 2630 * @param identifier the identifier 2631 * @return a new unparented simple name node 2632 * @exception IllegalArgumentException if the identifier is invalid 2633 */ newSimpleName(String identifier)2634 public SimpleName newSimpleName(String identifier) { 2635 if (identifier == null) { 2636 throw new IllegalArgumentException(); 2637 } 2638 SimpleName result = new SimpleName(this); 2639 result.setIdentifier(identifier); 2640 return result; 2641 } 2642 2643 //=============================== TYPES =========================== 2644 /** 2645 * Creates and returns a new unparented simple type node with the given 2646 * type name. 2647 * <p> 2648 * This method can be used to convert a name (<code>Name</code>) into a 2649 * type (<code>Type</code>) by wrapping it. 2650 * </p> 2651 * 2652 * @param typeName the name of the class or interface 2653 * @return a new unparented simple type node 2654 * @exception IllegalArgumentException if: 2655 * <ul> 2656 * <li>the node belongs to a different AST</li> 2657 * <li>the node already has a parent</li> 2658 * </ul> 2659 */ newSimpleType(Name typeName)2660 public SimpleType newSimpleType(Name typeName) { 2661 SimpleType result = new SimpleType(this); 2662 result.setName(typeName); 2663 return result; 2664 } 2665 2666 /** 2667 * Creates and returns a new unparented single member annotation node with 2668 * an unspecified type name and value. 2669 * 2670 * @return a new unparented single member annotation node 2671 * @exception UnsupportedOperationException if this operation is used in 2672 * a JLS2 AST 2673 * @since 3.1 2674 */ newSingleMemberAnnotation()2675 public SingleMemberAnnotation newSingleMemberAnnotation() { 2676 SingleMemberAnnotation result = new SingleMemberAnnotation(this); 2677 return result; 2678 } 2679 2680 /** 2681 * Creates an unparented single variable declaration node owned by this AST. 2682 * By default, the declaration is for a variable with an unspecified, but 2683 * legal, name and type; no modifiers; no array dimensions after the 2684 * variable; no initializer; not variable arity. 2685 * 2686 * @return a new unparented single variable declaration node 2687 */ newSingleVariableDeclaration()2688 public SingleVariableDeclaration newSingleVariableDeclaration() { 2689 SingleVariableDeclaration result = new SingleVariableDeclaration(this); 2690 return result; 2691 } 2692 2693 //=============================== EXPRESSIONS =========================== 2694 /** 2695 * Creates and returns a new unparented string literal node for 2696 * the empty string literal. 2697 * 2698 * @return a new unparented string literal node 2699 */ newStringLiteral()2700 public StringLiteral newStringLiteral() { 2701 return new StringLiteral(this); 2702 } 2703 2704 /** 2705 * Creates an unparented alternate super constructor ("super(...);") 2706 * invocation statement node owned by this AST. By default, there is no 2707 * qualifier, no type arguments, and the list of arguments is empty. 2708 * <p> 2709 * Note that this type of node is a Statement, whereas a regular 2710 * super method invocation is an Expression. The only valid use of these 2711 * statements are as the first statement of a constructor body. 2712 * </p> 2713 * 2714 * @return a new unparented super constructor invocation statement node 2715 */ newSuperConstructorInvocation()2716 public SuperConstructorInvocation newSuperConstructorInvocation() { 2717 SuperConstructorInvocation result = 2718 new SuperConstructorInvocation(this); 2719 return result; 2720 } 2721 2722 /** 2723 * Creates and returns a new unparented super field access expression node 2724 * owned by this AST. By default, the expression and field are both 2725 * unspecified, but legal, names. 2726 * 2727 * @return a new unparented super field access expression node 2728 */ newSuperFieldAccess()2729 public SuperFieldAccess newSuperFieldAccess() { 2730 SuperFieldAccess result = new SuperFieldAccess(this); 2731 return result; 2732 } 2733 2734 /** 2735 * Creates an unparented "super" method invocation expression node owned by 2736 * this AST. By default, the name of the method is unspecified (but legal), 2737 * there is no qualifier, no type arguments, and the list of arguments is empty. 2738 * 2739 * @return a new unparented "super" method invocation 2740 * expression node 2741 */ newSuperMethodInvocation()2742 public SuperMethodInvocation newSuperMethodInvocation() { 2743 SuperMethodInvocation result = new SuperMethodInvocation(this); 2744 return result; 2745 } 2746 2747 /** 2748 * Creates and returns a new unparented super method reference node owned by 2749 * this AST. By default, the name of the method is unspecified (but legal), 2750 * and there is no qualifier and no type arguments. 2751 * 2752 * @return a new unparented super method reference node 2753 * @since 3.10 2754 */ newSuperMethodReference()2755 public SuperMethodReference newSuperMethodReference() { 2756 SuperMethodReference result = new SuperMethodReference(this); 2757 return result; 2758 } 2759 2760 /** 2761 * Creates and returns a new unparented switch expression node 2762 * owned by this AST. By default, the expression is unspecified, but legal, 2763 * and there are no statements or switch cases. 2764 * 2765 * @return a new unparented labeled switch expression node 2766 * @since 3.18 2767 */ newSwitchExpression()2768 public SwitchExpression newSwitchExpression() { 2769 SwitchExpression result = new SwitchExpression(this); 2770 return result; 2771 } 2772 2773 /** 2774 * Creates a new unparented switch case statement node owned by 2775 * this AST. By default, the node has no expression, but legal, and 2776 * switchLabeledRule is false which indicates ":". 2777 * 2778 * @return a new unparented switch case node 2779 */ newSwitchCase()2780 public SwitchCase newSwitchCase() { 2781 return new SwitchCase(this); 2782 } 2783 2784 /** 2785 * Creates a new unparented switch statement node owned by this AST. 2786 * By default, the expression is unspecified, but legal, and there are 2787 * no statements or switch cases. 2788 * 2789 * @return a new unparented labeled statement node 2790 */ newSwitchStatement()2791 public SwitchStatement newSwitchStatement() { 2792 return new SwitchStatement(this); 2793 } 2794 2795 /** 2796 * Creates a new unparented synchronized statement node owned by this AST. 2797 * By default, the expression is unspecified, but legal, and the body is 2798 * an empty block. 2799 * 2800 * @return a new unparented synchronized statement node 2801 */ newSynchronizedStatement()2802 public SynchronizedStatement newSynchronizedStatement() { 2803 return new SynchronizedStatement(this); 2804 } 2805 2806 /** 2807 * Creates and returns a new tag element node. 2808 * Initially the new node has no tag name and an empty list of fragments. 2809 * <p> 2810 * Note that this node type is used only inside doc comments 2811 * ({@link Javadoc}). 2812 * </p> 2813 * 2814 * @return a new unparented tag element node 2815 * @since 3.0 2816 */ newTagElement()2817 public TagElement newTagElement() { 2818 TagElement result = new TagElement(this); 2819 return result; 2820 } 2821 2822 /** 2823 * Creates an unparented yield statement node owned by this AST. The yield statement has no 2824 * label/identifier/expression and is not implicit. 2825 * 2826 * @return a new unparented yield statement node 2827 * @since 3.20 2828 * @noreference This method is not intended to be referenced by clients. 2829 */ newTextBlock()2830 public TextBlock newTextBlock() { 2831 return new TextBlock(this); 2832 } 2833 2834 /** 2835 * Creates and returns a new text element node. 2836 * Initially the new node has an empty text string. 2837 * <p> 2838 * Note that this node type is used only inside doc comments 2839 * ({@link Javadoc Javadoc}). 2840 * </p> 2841 * 2842 * @return a new unparented text element node 2843 * @since 3.0 2844 */ newTextElement()2845 public TextElement newTextElement() { 2846 TextElement result = new TextElement(this); 2847 return result; 2848 } 2849 2850 /** 2851 * Creates and returns a new unparented "this" expression node 2852 * owned by this AST. By default, there is no qualifier. 2853 * 2854 * @return a new unparented "this" expression node 2855 */ newThisExpression()2856 public ThisExpression newThisExpression() { 2857 ThisExpression result = new ThisExpression(this); 2858 return result; 2859 } 2860 2861 /** 2862 * Creates a new unparented throw statement node owned by this AST. 2863 * By default, the expression is unspecified, but legal. 2864 * 2865 * @return a new unparented throw statement node 2866 */ newThrowStatement()2867 public ThrowStatement newThrowStatement() { 2868 return new ThrowStatement(this); 2869 } 2870 2871 /** 2872 * Creates a new unparented try statement node owned by this AST. 2873 * By default, the try statement has no resources, an empty block, no catch 2874 * clauses, and no finally block. 2875 * 2876 * @return a new unparented try statement node 2877 */ newTryStatement()2878 public TryStatement newTryStatement() { 2879 return new TryStatement(this); 2880 } 2881 2882 /** 2883 * Creates an unparented class declaration node owned by this AST. 2884 * The name of the class is an unspecified, but legal, name; 2885 * no modifiers; no doc comment; no superclass or superinterfaces; 2886 * and an empty class body. 2887 * <p> 2888 * To create an interface, use this method and then call 2889 * <code>TypeDeclaration.setInterface(true)</code>. 2890 * </p> 2891 * 2892 * @return a new unparented type declaration node 2893 */ newTypeDeclaration()2894 public TypeDeclaration newTypeDeclaration() { 2895 TypeDeclaration result = new TypeDeclaration(this); 2896 result.setInterface(false); 2897 return result; 2898 } 2899 2900 /** 2901 * Creates a new unparented local type declaration statement node 2902 * owned by this AST, for the given type declaration. 2903 * <p> 2904 * This method can be used to convert any kind of type declaration 2905 * (<code>AbstractTypeDeclaration</code>) into a statement 2906 * (<code>Statement</code>) by wrapping it. 2907 * </p> 2908 * 2909 * @param decl the type declaration 2910 * @return a new unparented local type declaration statement node 2911 * @exception IllegalArgumentException if: 2912 * <ul> 2913 * <li>the node belongs to a different AST</li> 2914 * <li>the node already has a parent</li> 2915 * </ul> 2916 * @since 3.0 2917 */ 2918 public TypeDeclarationStatement newTypeDeclarationStatement(AbstractTypeDeclaration decl)2919 newTypeDeclarationStatement(AbstractTypeDeclaration decl) { 2920 TypeDeclarationStatement result = new TypeDeclarationStatement(this); 2921 if (this.apiLevel == AST.JLS2) { 2922 result.internalSetTypeDeclaration((TypeDeclaration) decl); 2923 } 2924 if (this.apiLevel >= AST.JLS3) { 2925 result.setDeclaration(decl); 2926 } 2927 return result; 2928 } 2929 2930 /** 2931 * Creates a new unparented local type declaration statement node 2932 * owned by this AST, for the given type declaration. 2933 * <p> 2934 * This method can be used to convert a type declaration 2935 * (<code>TypeDeclaration</code>) into a statement 2936 * (<code>Statement</code>) by wrapping it. 2937 * </p> 2938 * 2939 * @param decl the type declaration 2940 * @return a new unparented local type declaration statement node 2941 * @exception IllegalArgumentException if: 2942 * <ul> 2943 * <li>the node belongs to a different AST</li> 2944 * <li>the node already has a parent</li> 2945 * </ul> 2946 */ 2947 public TypeDeclarationStatement newTypeDeclarationStatement(TypeDeclaration decl)2948 newTypeDeclarationStatement(TypeDeclaration decl) { 2949 TypeDeclarationStatement result = new TypeDeclarationStatement(this); 2950 result.setDeclaration(decl); 2951 return result; 2952 } 2953 2954 /** 2955 * Creates and returns a new unparented type literal expression node 2956 * owned by this AST. By default, the type is unspecified (but legal). 2957 * 2958 * @return a new unparented type literal node 2959 */ newTypeLiteral()2960 public TypeLiteral newTypeLiteral() { 2961 TypeLiteral result = new TypeLiteral(this); 2962 return result; 2963 } 2964 2965 /** 2966 * Creates an unparented type method reference node owned by this AST. 2967 * By default, the type and method name are unspecified (but legal), 2968 * and there are no type arguments. 2969 * 2970 * @return a new unparented type method reference node 2971 * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST 2972 * @since 3.10 2973 */ newTypeMethodReference()2974 public TypeMethodReference newTypeMethodReference() { 2975 TypeMethodReference result = new TypeMethodReference(this); 2976 return result; 2977 } 2978 2979 /** 2980 * Creates and returns a new unparented type parameter type node with an 2981 * unspecified type variable name and an empty list of type bounds. 2982 * 2983 * @return a new unparented type parameter node 2984 * @exception UnsupportedOperationException if this operation is used in 2985 * a JLS2 AST 2986 * @since 3.1 2987 */ newTypeParameter()2988 public TypeParameter newTypeParameter() { 2989 TypeParameter result = new TypeParameter(this); 2990 return result; 2991 } 2992 2993 /** 2994 * Creates a new unparented union type node owned by this AST. 2995 * By default, the union type has no types. 2996 * 2997 * @return a new unparented UnionType node 2998 * @exception UnsupportedOperationException if this operation is used in 2999 * a JLS2 or JLS3 AST 3000 * @since 3.7.1 3001 */ newUnionType()3002 public UnionType newUnionType() { 3003 return new UnionType(this); 3004 } 3005 3006 /** 3007 * Creates and returns a new unparented uses directive 3008 * node for an unspecified, but legal, name; 3009 * 3010 * @return a new unparented uses directive node 3011 * @exception UnsupportedOperationException if this operation is used in level less than JLS9 3012 * @since 3.14 3013 */ newUsesDirective()3014 public UsesDirective newUsesDirective() { 3015 UsesDirective result = new UsesDirective(this); 3016 return result; 3017 } 3018 3019 /** 3020 * Creates a new unparented intersection type node owned by this AST. 3021 * By default, the intersection type has no types. 3022 * 3023 * @return a new unparented IntersectionType node 3024 * @exception UnsupportedOperationException if this operation is used in 3025 * a JLS2, JLS3 or JLS4 AST 3026 * @since 3.10 3027 */ newIntersectionType()3028 public IntersectionType newIntersectionType() { 3029 return new IntersectionType(this); 3030 } 3031 3032 /** 3033 * Creates a new unparented local variable declaration expression node 3034 * owned by this AST, for the given variable declaration fragment. By 3035 * default, there are no modifiers and the base type is unspecified 3036 * (but legal). 3037 * <p> 3038 * This method can be used to convert a variable declaration fragment 3039 * (<code>VariableDeclarationFragment</code>) into an expression 3040 * (<code>Expression</code>) by wrapping it. Additional variable 3041 * declaration fragments can be added afterwards. 3042 * </p> 3043 * 3044 * @param fragment the first variable declaration fragment 3045 * @return a new unparented variable declaration expression node 3046 * @exception IllegalArgumentException if: 3047 * <ul> 3048 * <li>the node belongs to a different AST</li> 3049 * <li>the node already has a parent</li> 3050 * <li>the given fragment is null</li> 3051 * </ul> 3052 */ 3053 public VariableDeclarationExpression newVariableDeclarationExpression(VariableDeclarationFragment fragment)3054 newVariableDeclarationExpression(VariableDeclarationFragment fragment) { 3055 if (fragment == null) { 3056 throw new IllegalArgumentException(); 3057 } 3058 VariableDeclarationExpression result = 3059 new VariableDeclarationExpression(this); 3060 result.fragments().add(fragment); 3061 return result; 3062 } 3063 3064 /** 3065 * Creates an unparented variable declaration fragment node owned by this 3066 * AST. By default, the fragment is for a variable with an unspecified, but 3067 * legal, name; no extra array dimensions; and no initializer. 3068 * 3069 * @return a new unparented variable declaration fragment node 3070 */ newVariableDeclarationFragment()3071 public VariableDeclarationFragment newVariableDeclarationFragment() { 3072 VariableDeclarationFragment result = new VariableDeclarationFragment(this); 3073 return result; 3074 } 3075 3076 //=============================== STATEMENTS =========================== 3077 /** 3078 * Creates a new unparented local variable declaration statement node 3079 * owned by this AST, for the given variable declaration fragment. 3080 * By default, there are no modifiers and the base type is unspecified 3081 * (but legal). 3082 * <p> 3083 * This method can be used to convert a variable declaration fragment 3084 * (<code>VariableDeclarationFragment</code>) into a statement 3085 * (<code>Statement</code>) by wrapping it. Additional variable 3086 * declaration fragments can be added afterwards. 3087 * </p> 3088 * 3089 * @param fragment the variable declaration fragment 3090 * @return a new unparented variable declaration statement node 3091 * @exception IllegalArgumentException if: 3092 * <ul> 3093 * <li>the node belongs to a different AST</li> 3094 * <li>the node already has a parent</li> 3095 * <li>the variable declaration fragment is null</li> 3096 * </ul> 3097 */ 3098 public VariableDeclarationStatement newVariableDeclarationStatement(VariableDeclarationFragment fragment)3099 newVariableDeclarationStatement(VariableDeclarationFragment fragment) { 3100 if (fragment == null) { 3101 throw new IllegalArgumentException(); 3102 } 3103 VariableDeclarationStatement result = 3104 new VariableDeclarationStatement(this); 3105 result.fragments().add(fragment); 3106 return result; 3107 } 3108 3109 /** 3110 * Creates a new unparented while statement node owned by this AST. 3111 * By default, the expression is unspecified (but legal), and 3112 * the body statement is an empty block. 3113 * 3114 * @return a new unparented while statement node 3115 */ newWhileStatement()3116 public WhileStatement newWhileStatement() { 3117 return new WhileStatement(this); 3118 } 3119 3120 /** 3121 * Creates and returns a new unparented wildcard type node with no 3122 * type bound. 3123 * 3124 * @return a new unparented wildcard type node 3125 * @exception UnsupportedOperationException if this operation is used in 3126 * a JLS2 AST 3127 * @since 3.1 3128 */ newWildcardType()3129 public WildcardType newWildcardType() { 3130 WildcardType result = new WildcardType(this); 3131 return result; 3132 } 3133 3134 /** 3135 * Creates an unparented yield statement node owned by this AST. The yield statement has no 3136 * label/identifier/expression and is not implicit. 3137 * 3138 * @return a new unparented yield statement node 3139 * @since 3.20 3140 * @noreference This method is not intended to be referenced by clients. 3141 */ newYieldStatement()3142 public YieldStatement newYieldStatement() { 3143 return new YieldStatement(this); 3144 } 3145 3146 /** 3147 * Reports that the given node has just gained a child. 3148 * 3149 * @param node the node that was modified 3150 * @param child the node that was added as a child 3151 * @param property the child or child list property descriptor 3152 * @since 3.0 3153 */ postAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property)3154 void postAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) { 3155 // IMPORTANT: this method is called by readers during lazy init 3156 synchronized (this.internalASTLock) { 3157 // guard against concurrent access by a reader doing lazy init 3158 if (this.disableEvents > 0) { 3159 // doing lazy init OR already processing an event 3160 // System.out.println("[BOUNCE ADD]"); 3161 return; 3162 } else { 3163 disableEvents(); 3164 } 3165 } 3166 try { 3167 this.eventHandler.postAddChildEvent(node, child, property); 3168 // N.B. even if event handler blows up, the AST is not 3169 // corrupted since node has already been changed 3170 } finally { 3171 reenableEvents(); 3172 } 3173 } 3174 3175 /** 3176 * Reports that the given node has just been cloned. 3177 * 3178 * @param node the node that was cloned 3179 * @param clone the clone of <code>node</code> 3180 * @since 3.0 3181 */ postCloneNodeEvent(ASTNode node, ASTNode clone)3182 void postCloneNodeEvent(ASTNode node, ASTNode clone) { 3183 synchronized (this.internalASTLock) { 3184 // guard against concurrent access by a reader doing lazy init 3185 if (this.disableEvents > 0) { 3186 // doing lazy init OR already processing an event 3187 // System.out.println("[BOUNCE CLONE]"); 3188 return; 3189 } else { 3190 disableEvents(); 3191 } 3192 } 3193 try { 3194 this.eventHandler.postCloneNodeEvent(node, clone); 3195 // N.B. even if event handler blows up, the AST is not 3196 // corrupted since node has already been changed 3197 } finally { 3198 reenableEvents(); 3199 } 3200 } 3201 3202 /** 3203 * Reports that the given node jsut lost a child. 3204 * 3205 * @param node the node that was modified 3206 * @param child the child node that was removed 3207 * @param property the child or child list property descriptor 3208 * @since 3.0 3209 */ postRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property)3210 void postRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) { 3211 // IMPORTANT: this method is called by readers during lazy init 3212 synchronized (this.internalASTLock) { 3213 // guard against concurrent access by a reader doing lazy init 3214 if (this.disableEvents > 0) { 3215 // doing lazy init OR already processing an event 3216 // System.out.println("[BOUNCE DEL]"); 3217 return; 3218 } else { 3219 disableEvents(); 3220 } 3221 } 3222 try { 3223 this.eventHandler.postRemoveChildEvent(node, child, property); 3224 // N.B. even if event handler blows up, the AST is not 3225 // corrupted since node has not been changed yet 3226 } finally { 3227 reenableEvents(); 3228 } 3229 } 3230 3231 /** 3232 * Reports that the given node has just had a child replaced. 3233 * 3234 * @param node the node modified 3235 * @param child the child removed 3236 * @param newChild the replacement child 3237 * @param property the child or child list property descriptor 3238 * @since 3.0 3239 */ postReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property)3240 void postReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) { 3241 // IMPORTANT: this method is called by readers during lazy init 3242 synchronized (this.internalASTLock) { 3243 // guard against concurrent access by a reader doing lazy init 3244 if (this.disableEvents > 0) { 3245 // doing lazy init OR already processing an event 3246 // System.out.println("[BOUNCE REP]"); 3247 return; 3248 } else { 3249 disableEvents(); 3250 } 3251 } 3252 try { 3253 this.eventHandler.postReplaceChildEvent(node, child, newChild, property); 3254 // N.B. even if event handler blows up, the AST is not 3255 // corrupted since node has not been changed yet 3256 } finally { 3257 reenableEvents(); 3258 } 3259 } 3260 3261 /** 3262 * Reports that the given node has just changed the value of a 3263 * non-child property. 3264 * 3265 * @param node the node that was modified 3266 * @param property the property descriptor 3267 * @since 3.0 3268 */ postValueChangeEvent(ASTNode node, SimplePropertyDescriptor property)3269 void postValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) { 3270 // IMPORTANT: this method is called by readers during lazy init 3271 synchronized (this.internalASTLock) { 3272 // guard against concurrent access by a reader doing lazy init 3273 if (this.disableEvents > 0) { 3274 // doing lazy init OR already processing an event 3275 // System.out.println("[BOUNCE CHANGE]"); 3276 return; 3277 } else { 3278 disableEvents(); 3279 } 3280 } 3281 try { 3282 this.eventHandler.postValueChangeEvent(node, property); 3283 // N.B. even if event handler blows up, the AST is not 3284 // corrupted since node has already been changed 3285 } finally { 3286 reenableEvents(); 3287 } 3288 } 3289 3290 /** 3291 * Reports that the given node is about to gain a child. 3292 * 3293 * @param node the node that to be modified 3294 * @param child the node that to be added as a child 3295 * @param property the child or child list property descriptor 3296 * @since 3.0 3297 */ preAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property)3298 void preAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) { 3299 // IMPORTANT: this method is called by readers during lazy init 3300 synchronized (this.internalASTLock) { 3301 // guard against concurrent access by a reader doing lazy init 3302 if (this.disableEvents > 0) { 3303 // doing lazy init OR already processing an event 3304 // System.out.println("[BOUNCE ADD]"); 3305 return; 3306 } else { 3307 disableEvents(); 3308 } 3309 } 3310 try { 3311 this.eventHandler.preAddChildEvent(node, child, property); 3312 // N.B. even if event handler blows up, the AST is not 3313 // corrupted since node has already been changed 3314 } finally { 3315 reenableEvents(); 3316 } 3317 } 3318 3319 /** 3320 * Reports that the given node is about to be cloned. 3321 * 3322 * @param node the node to be cloned 3323 * @since 3.0 3324 */ preCloneNodeEvent(ASTNode node)3325 void preCloneNodeEvent(ASTNode node) { 3326 synchronized (this.internalASTLock) { 3327 // guard against concurrent access by a reader doing lazy init 3328 if (this.disableEvents > 0) { 3329 // doing lazy init OR already processing an event 3330 // System.out.println("[BOUNCE CLONE]"); 3331 return; 3332 } else { 3333 disableEvents(); 3334 } 3335 } 3336 try { 3337 this.eventHandler.preCloneNodeEvent(node); 3338 // N.B. even if event handler blows up, the AST is not 3339 // corrupted since node has already been changed 3340 } finally { 3341 reenableEvents(); 3342 } 3343 } 3344 3345 /** 3346 * Reports that the given node is about to lose a child. 3347 * 3348 * @param node the node about to be modified 3349 * @param child the node about to be removed 3350 * @param property the child or child list property descriptor 3351 * @since 3.0 3352 */ preRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property)3353 void preRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) { 3354 // IMPORTANT: this method is called by readers during lazy init 3355 synchronized (this.internalASTLock) { 3356 // guard against concurrent access by a reader doing lazy init 3357 if (this.disableEvents > 0) { 3358 // doing lazy init OR already processing an event 3359 // System.out.println("[BOUNCE DEL]"); 3360 return; 3361 } else { 3362 disableEvents(); 3363 } 3364 } 3365 try { 3366 this.eventHandler.preRemoveChildEvent(node, child, property); 3367 // N.B. even if event handler blows up, the AST is not 3368 // corrupted since node has not been changed yet 3369 } finally { 3370 reenableEvents(); 3371 } 3372 } 3373 3374 /** 3375 * Reports that the given node is about have a child replaced. 3376 * 3377 * @param node the node about to be modified 3378 * @param child the child node about to be removed 3379 * @param newChild the replacement child 3380 * @param property the child or child list property descriptor 3381 * @since 3.0 3382 */ preReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property)3383 void preReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) { 3384 // IMPORTANT: this method is called by readers during lazy init 3385 synchronized (this.internalASTLock) { 3386 // guard against concurrent access by a reader doing lazy init 3387 if (this.disableEvents > 0) { 3388 // doing lazy init OR already processing an event 3389 // System.out.println("[BOUNCE REP]"); 3390 return; 3391 } else { 3392 disableEvents(); 3393 } 3394 } 3395 try { 3396 this.eventHandler.preReplaceChildEvent(node, child, newChild, property); 3397 // N.B. even if event handler blows up, the AST is not 3398 // corrupted since node has not been changed yet 3399 } finally { 3400 reenableEvents(); 3401 } 3402 } 3403 3404 /** 3405 * Reports that the given node is about to change the value of a 3406 * non-child property. 3407 * 3408 * @param node the node to be modified 3409 * @param property the property descriptor 3410 * @since 3.0 3411 */ preValueChangeEvent(ASTNode node, SimplePropertyDescriptor property)3412 void preValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) { 3413 // IMPORTANT: this method is called by readers during lazy init 3414 synchronized (this.internalASTLock) { 3415 // guard against concurrent access by a reader doing lazy init 3416 if (this.disableEvents > 0) { 3417 // doing lazy init OR already processing an event 3418 // System.out.println("[BOUNCE CHANGE]"); 3419 return; 3420 } else { 3421 disableEvents(); 3422 } 3423 } 3424 try { 3425 this.eventHandler.preValueChangeEvent(node, property); 3426 // N.B. even if event handler blows up, the AST is not 3427 // corrupted since node has already been changed 3428 } finally { 3429 reenableEvents(); 3430 } 3431 } 3432 3433 /** 3434 * Enables the recording of changes to the given compilation 3435 * unit and its descendents. The compilation unit must have 3436 * been created by <code>ASTParser</code> and still be in 3437 * its original state. Once recording is on, 3438 * arbitrary changes to the subtree rooted at the compilation 3439 * unit are recorded internally. Once the modification has 3440 * been completed, call <code>rewrite</code> to get an object 3441 * representing the corresponding edits to the original 3442 * source code string. 3443 * 3444 * @exception IllegalArgumentException if this compilation unit is 3445 * marked as unmodifiable, or if this compilation unit has already 3446 * been tampered with, or if recording has already been enabled, 3447 * or if <code>root</code> is not owned by this AST 3448 * @see CompilationUnit#recordModifications() 3449 * @since 3.0 3450 */ recordModifications(CompilationUnit root)3451 void recordModifications(CompilationUnit root) { 3452 if(this.modificationCount != this.originalModificationCount) { 3453 throw new IllegalArgumentException("AST is already modified"); //$NON-NLS-1$ 3454 } else if(this.rewriter != null) { 3455 throw new IllegalArgumentException("AST modifications are already recorded"); //$NON-NLS-1$ 3456 } else if((root.getFlags() & ASTNode.PROTECT) != 0) { 3457 throw new IllegalArgumentException("Root node is unmodifiable"); //$NON-NLS-1$ 3458 } else if(root.getAST() != this) { 3459 throw new IllegalArgumentException("Root node is not owned by this ast"); //$NON-NLS-1$ 3460 } 3461 3462 this.rewriter = new InternalASTRewrite(root); 3463 setEventHandler(this.rewriter); 3464 } 3465 3466 //=============================== ANNOTATIONS ==================== 3467 3468 /** 3469 * Reenable events. 3470 * This method is thread-safe for AST readers. 3471 * 3472 * @see #disableEvents() 3473 * @since 3.0 3474 */ reenableEvents()3475 final void reenableEvents() { 3476 synchronized (this.internalASTLock) { 3477 // guard against concurrent access by another reader 3478 this.disableEvents--; 3479 } 3480 } 3481 3482 /** 3483 * Returns the type binding for a "well known" type. 3484 * <p> 3485 * Note that bindings are generally unavailable unless requested when the 3486 * AST is being built. 3487 * </p> 3488 * <p> 3489 * The following type names are supported: 3490 * <ul> 3491 * <li><code>"boolean"</code></li> 3492 * <li><code>"byte"</code></li> 3493 * <li><code>"char"</code></li> 3494 * <li><code>"double"</code></li> 3495 * <li><code>"float"</code></li> 3496 * <li><code>"int"</code></li> 3497 * <li><code>"long"</code></li> 3498 * <li><code>"short"</code></li> 3499 * <li><code>"void"</code></li> 3500 * <li><code>"java.lang.AssertionError"</code> (since 3.7)</li> 3501 * <li><code>"java.lang.Boolean"</code> (since 3.1)</li> 3502 * <li><code>"java.lang.Byte"</code> (since 3.1)</li> 3503 * <li><code>"java.lang.Character"</code> (since 3.1)</li> 3504 * <li><code>"java.lang.Class"</code></li> 3505 * <li><code>"java.lang.Cloneable"</code></li> 3506 * <li><code>"java.lang.Double"</code> (since 3.1)</li> 3507 * <li><code>"java.lang.Error"</code></li> 3508 * <li><code>"java.lang.Exception"</code></li> 3509 * <li><code>"java.lang.Float"</code> (since 3.1)</li> 3510 * <li><code>"java.lang.Integer"</code> (since 3.1)</li> 3511 * <li><code>"java.lang.Long"</code> (since 3.1)</li> 3512 * <li><code>"java.lang.Object"</code></li> 3513 * <li><code>"java.lang.RuntimeException"</code></li> 3514 * <li><code>"java.lang.Short"</code> (since 3.1)</li> 3515 * <li><code>"java.lang.String"</code></li> 3516 * <li><code>"java.lang.StringBuffer"</code></li> 3517 * <li><code>"java.lang.Throwable"</code></li> 3518 * <li><code>"java.lang.Void"</code> (since 3.1)</li> 3519 * <li><code>"java.io.Serializable"</code></li> 3520 * </ul> 3521 * 3522 * @param name the name of a well known type 3523 * @return the corresponding type binding, or <code>null</code> if the 3524 * named type is not considered well known or if no binding can be found 3525 * for it 3526 */ resolveWellKnownType(String name)3527 public ITypeBinding resolveWellKnownType(String name) { 3528 if (name == null) { 3529 return null; 3530 } 3531 return getBindingResolver().resolveWellKnownType(name); 3532 } 3533 3534 /** 3535 * Converts all modifications recorded into an object 3536 * representing the corresponding text edits to the 3537 * given document containing the original source 3538 * code for the compilation unit that gave rise to 3539 * this AST. 3540 * 3541 * @param document original document containing source code 3542 * for the compilation unit 3543 * @param options the table of formatter options 3544 * (key type: <code>String</code>; value type: <code>String</code>); 3545 * or <code>null</code> to use the standard global options 3546 * {@link JavaCore#getOptions() JavaCore.getOptions()}. 3547 * @return text edit object describing the changes to the 3548 * document corresponding to the recorded AST modifications 3549 * @exception IllegalArgumentException if the document passed is 3550 * <code>null</code> or does not correspond to this AST 3551 * @exception IllegalStateException if <code>recordModifications</code> 3552 * was not called to enable recording 3553 * @see CompilationUnit#rewrite(IDocument, Map) 3554 * @since 3.0 3555 */ rewrite(IDocument document, Map options)3556 TextEdit rewrite(IDocument document, Map options) { 3557 if (document == null) { 3558 throw new IllegalArgumentException(); 3559 } 3560 if (this.rewriter == null) { 3561 throw new IllegalStateException("Modifications record is not enabled"); //$NON-NLS-1$ 3562 } 3563 return this.rewriter.rewriteAST(document, options); 3564 } 3565 3566 /** 3567 * Sets the binding resolver for this AST. 3568 * 3569 * @param resolver the new binding resolver for this AST 3570 */ setBindingResolver(BindingResolver resolver)3571 void setBindingResolver(BindingResolver resolver) { 3572 if (resolver == null) { 3573 throw new IllegalArgumentException(); 3574 } 3575 this.resolver = resolver; 3576 } 3577 3578 /** 3579 * Sets default node flags of new nodes of this AST. 3580 * 3581 * @param flag node flags of new nodes of this AST 3582 * @since 3.0 3583 */ setDefaultNodeFlag(int flag)3584 void setDefaultNodeFlag(int flag) { 3585 this.defaultNodeFlag = flag; 3586 } 3587 3588 /** 3589 * Sets the event handler for this AST. 3590 * 3591 * @param eventHandler the event handler for this AST 3592 * @since 3.0 3593 */ setEventHandler(NodeEventHandler eventHandler)3594 void setEventHandler(NodeEventHandler eventHandler) { 3595 if (this.eventHandler == null) { 3596 throw new IllegalArgumentException(); 3597 } 3598 this.eventHandler = eventHandler; 3599 } 3600 setFlag(int newValue)3601 void setFlag(int newValue) { 3602 this.bits |= newValue; 3603 } 3604 3605 /** 3606 * Set <code>originalModificationCount</code> to the current modification count 3607 * 3608 * @since 3.0 3609 */ setOriginalModificationCount(long count)3610 void setOriginalModificationCount(long count) { 3611 this.originalModificationCount = count; 3612 } 3613 3614 /** 3615 * Checks that this AST operation is only used when 3616 * building level JLS2 ASTs. 3617 3618 * @exception UnsupportedOperationException 3619 * @since 3.0 3620 */ supportedOnlyIn2()3621 void supportedOnlyIn2() { 3622 if (this.apiLevel != AST.JLS2) { 3623 throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$ 3624 } 3625 } 3626 3627 /** 3628 * Checks that this AST operation is not used when 3629 * building level JLS2 ASTs. 3630 3631 * @exception UnsupportedOperationException 3632 * @since 3.0 3633 */ unsupportedIn2()3634 void unsupportedIn2() { 3635 if (this.apiLevel == AST.JLS2) { 3636 throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$ 3637 } 3638 } 3639 3640 3641 /** 3642 * 3643 * @return If previewEnabled flag is set to <code>true</code>, return <code>true</code> else <code>false</code> 3644 * @since 3.21 3645 * @noreference This method is not intended to be referenced by clients. 3646 */ isPreviewEnabledSet()3647 public boolean isPreviewEnabledSet() { 3648 return this.previewEnabled; 3649 } 3650 3651 /** 3652 * 3653 * @return If preview is enabled and apiLevel is latest, return <code>true</code> else <code>false</code> 3654 * @since 3.19 3655 */ isPreviewEnabled()3656 public boolean isPreviewEnabled() { 3657 if (this.apiLevel == AST.JLS_Latest && this.previewEnabled) { 3658 return true; 3659 } 3660 return false; 3661 } 3662 } 3663