1 /* 2 * Copyright (C) 2007-2010 Júlio Vilmar Gesser. 3 * Copyright (C) 2011, 2013-2016 The JavaParser Team. 4 * 5 * This file is part of JavaParser. 6 * 7 * JavaParser can be used either under the terms of 8 * a) the GNU Lesser General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * b) the terms of the Apache License 12 * 13 * You should have received a copy of both licenses in LICENCE.LGPL and 14 * LICENCE.APACHE. Please refer to those files for details. 15 * 16 * JavaParser is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU Lesser General Public License for more details. 20 */ 21 package com.github.javaparser.ast.stmt; 22 23 import com.github.javaparser.TokenRange; 24 import com.github.javaparser.ast.AllFieldsConstructor; 25 import com.github.javaparser.ast.Node; 26 import com.github.javaparser.ast.NodeList; 27 import com.github.javaparser.ast.expr.Expression; 28 import com.github.javaparser.ast.observer.ObservableProperty; 29 import com.github.javaparser.ast.visitor.CloneVisitor; 30 import com.github.javaparser.ast.visitor.GenericVisitor; 31 import com.github.javaparser.ast.visitor.VoidVisitor; 32 import com.github.javaparser.metamodel.JavaParserMetaModel; 33 import com.github.javaparser.metamodel.OptionalProperty; 34 import com.github.javaparser.metamodel.TryStmtMetaModel; 35 import java.util.Optional; 36 import static com.github.javaparser.utils.Utils.assertNotNull; 37 import java.util.function.Consumer; 38 import com.github.javaparser.ast.Generated; 39 40 /** 41 * <h1>The try statement</h1> 42 * <h2>Java 1.0-6</h2> 43 * <pre> 44 * try { 45 * // ... 46 * } catch (IOException e) { 47 * // ... 48 * } finally { 49 * // ... 50 * } 51 * </pre> 52 * In this code, "// do things" is the content of the tryBlock, there is one catch clause that catches IOException e, 53 * and there is a finally block. 54 * <p> 55 * The catch and finally blocks are optional, but they should not be empty at the same time. 56 * <h2>Java 7-8</h2> 57 * <pre> 58 * try (InputStream i = new FileInputStream("file")) { 59 * // ... 60 * } catch (IOException|NullPointerException e) { 61 * // ... 62 * } finally { 63 * // ... 64 * } 65 * </pre> 66 * Java 7 introduced two things: 67 * <ul> 68 * <li>Resources can be specified after "try", but only variable declarations (VariableDeclarationExpr.)</li> 69 * <li>A single catch can catch multiple exception types. This uses the IntersectionType.</li> 70 * </ul> 71 * <h2>Java 9+</h2> 72 * <pre> 73 * try (r) { 74 * // ... 75 * } catch (IOException|NullPointerException e) { 76 * // ... 77 * } finally { 78 * // ... 79 * } 80 * </pre> 81 * Java 9 finishes resources: you can now refer to a resource that was declared somewhere else. 82 * The following types are allowed: 83 * <ul> 84 * <li>VariableDeclarationExpr: "X x = new X()" like in Java 7-8.</li> 85 * <li>NameExpr: "a".</li> 86 * <li>FieldAccessExpr: "x.y.z", "super.test" etc.</li> 87 * </ul> 88 * 89 * @author Julio Vilmar Gesser 90 * @see CatchClause 91 * @see com.github.javaparser.ast.type.IntersectionType 92 * @see com.github.javaparser.ast.expr.FieldAccessExpr 93 * @see com.github.javaparser.ast.expr.NameExpr 94 */ 95 public class TryStmt extends Statement { 96 97 private NodeList<Expression> resources; 98 99 private BlockStmt tryBlock; 100 101 private NodeList<CatchClause> catchClauses; 102 103 @OptionalProperty 104 private BlockStmt finallyBlock; 105 TryStmt()106 public TryStmt() { 107 this(null, new NodeList<>(), new BlockStmt(), new NodeList<>(), null); 108 } 109 TryStmt(final BlockStmt tryBlock, final NodeList<CatchClause> catchClauses, final BlockStmt finallyBlock)110 public TryStmt(final BlockStmt tryBlock, final NodeList<CatchClause> catchClauses, final BlockStmt finallyBlock) { 111 this(null, new NodeList<>(), tryBlock, catchClauses, finallyBlock); 112 } 113 114 @AllFieldsConstructor TryStmt(NodeList<Expression> resources, final BlockStmt tryBlock, final NodeList<CatchClause> catchClauses, final BlockStmt finallyBlock)115 public TryStmt(NodeList<Expression> resources, final BlockStmt tryBlock, final NodeList<CatchClause> catchClauses, final BlockStmt finallyBlock) { 116 this(null, resources, tryBlock, catchClauses, finallyBlock); 117 } 118 119 /** 120 * This constructor is used by the parser and is considered private. 121 */ 122 @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator") TryStmt(TokenRange tokenRange, NodeList<Expression> resources, BlockStmt tryBlock, NodeList<CatchClause> catchClauses, BlockStmt finallyBlock)123 public TryStmt(TokenRange tokenRange, NodeList<Expression> resources, BlockStmt tryBlock, NodeList<CatchClause> catchClauses, BlockStmt finallyBlock) { 124 super(tokenRange); 125 setResources(resources); 126 setTryBlock(tryBlock); 127 setCatchClauses(catchClauses); 128 setFinallyBlock(finallyBlock); 129 customInitialization(); 130 } 131 132 @Override 133 @Generated("com.github.javaparser.generator.core.node.AcceptGenerator") accept(final GenericVisitor<R, A> v, final A arg)134 public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) { 135 return v.visit(this, arg); 136 } 137 138 @Override 139 @Generated("com.github.javaparser.generator.core.node.AcceptGenerator") accept(final VoidVisitor<A> v, final A arg)140 public <A> void accept(final VoidVisitor<A> v, final A arg) { 141 v.visit(this, arg); 142 } 143 144 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") getCatchClauses()145 public NodeList<CatchClause> getCatchClauses() { 146 return catchClauses; 147 } 148 149 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") getFinallyBlock()150 public Optional<BlockStmt> getFinallyBlock() { 151 return Optional.ofNullable(finallyBlock); 152 } 153 154 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") getTryBlock()155 public BlockStmt getTryBlock() { 156 return tryBlock; 157 } 158 159 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") getResources()160 public NodeList<Expression> getResources() { 161 return resources; 162 } 163 164 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") setCatchClauses(final NodeList<CatchClause> catchClauses)165 public TryStmt setCatchClauses(final NodeList<CatchClause> catchClauses) { 166 assertNotNull(catchClauses); 167 if (catchClauses == this.catchClauses) { 168 return (TryStmt) this; 169 } 170 notifyPropertyChange(ObservableProperty.CATCH_CLAUSES, this.catchClauses, catchClauses); 171 if (this.catchClauses != null) 172 this.catchClauses.setParentNode(null); 173 this.catchClauses = catchClauses; 174 setAsParentNodeOf(catchClauses); 175 return this; 176 } 177 178 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") setFinallyBlock(final BlockStmt finallyBlock)179 public TryStmt setFinallyBlock(final BlockStmt finallyBlock) { 180 if (finallyBlock == this.finallyBlock) { 181 return (TryStmt) this; 182 } 183 notifyPropertyChange(ObservableProperty.FINALLY_BLOCK, this.finallyBlock, finallyBlock); 184 if (this.finallyBlock != null) 185 this.finallyBlock.setParentNode(null); 186 this.finallyBlock = finallyBlock; 187 setAsParentNodeOf(finallyBlock); 188 return this; 189 } 190 191 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") setTryBlock(final BlockStmt tryBlock)192 public TryStmt setTryBlock(final BlockStmt tryBlock) { 193 assertNotNull(tryBlock); 194 if (tryBlock == this.tryBlock) { 195 return (TryStmt) this; 196 } 197 notifyPropertyChange(ObservableProperty.TRY_BLOCK, this.tryBlock, tryBlock); 198 if (this.tryBlock != null) 199 this.tryBlock.setParentNode(null); 200 this.tryBlock = tryBlock; 201 setAsParentNodeOf(tryBlock); 202 return this; 203 } 204 205 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") setResources(final NodeList<Expression> resources)206 public TryStmt setResources(final NodeList<Expression> resources) { 207 assertNotNull(resources); 208 if (resources == this.resources) { 209 return (TryStmt) this; 210 } 211 notifyPropertyChange(ObservableProperty.RESOURCES, this.resources, resources); 212 if (this.resources != null) 213 this.resources.setParentNode(null); 214 this.resources = resources; 215 setAsParentNodeOf(resources); 216 return this; 217 } 218 219 @Override 220 @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") remove(Node node)221 public boolean remove(Node node) { 222 if (node == null) 223 return false; 224 for (int i = 0; i < catchClauses.size(); i++) { 225 if (catchClauses.get(i) == node) { 226 catchClauses.remove(i); 227 return true; 228 } 229 } 230 if (finallyBlock != null) { 231 if (node == finallyBlock) { 232 removeFinallyBlock(); 233 return true; 234 } 235 } 236 for (int i = 0; i < resources.size(); i++) { 237 if (resources.get(i) == node) { 238 resources.remove(i); 239 return true; 240 } 241 } 242 return super.remove(node); 243 } 244 245 @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") removeFinallyBlock()246 public TryStmt removeFinallyBlock() { 247 return setFinallyBlock((BlockStmt) null); 248 } 249 250 @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") removeTryBlock()251 public TryStmt removeTryBlock() { 252 return setTryBlock((BlockStmt) null); 253 } 254 255 @Override 256 @Generated("com.github.javaparser.generator.core.node.CloneGenerator") clone()257 public TryStmt clone() { 258 return (TryStmt) accept(new CloneVisitor(), null); 259 } 260 261 @Override 262 @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator") getMetaModel()263 public TryStmtMetaModel getMetaModel() { 264 return JavaParserMetaModel.tryStmtMetaModel; 265 } 266 267 @Override 268 @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator") replace(Node node, Node replacementNode)269 public boolean replace(Node node, Node replacementNode) { 270 if (node == null) 271 return false; 272 for (int i = 0; i < catchClauses.size(); i++) { 273 if (catchClauses.get(i) == node) { 274 catchClauses.set(i, (CatchClause) replacementNode); 275 return true; 276 } 277 } 278 if (finallyBlock != null) { 279 if (node == finallyBlock) { 280 setFinallyBlock((BlockStmt) replacementNode); 281 return true; 282 } 283 } 284 for (int i = 0; i < resources.size(); i++) { 285 if (resources.get(i) == node) { 286 resources.set(i, (Expression) replacementNode); 287 return true; 288 } 289 } 290 if (node == tryBlock) { 291 setTryBlock((BlockStmt) replacementNode); 292 return true; 293 } 294 return super.replace(node, replacementNode); 295 } 296 297 @Override 298 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") isTryStmt()299 public boolean isTryStmt() { 300 return true; 301 } 302 303 @Override 304 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") asTryStmt()305 public TryStmt asTryStmt() { 306 return this; 307 } 308 309 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") ifTryStmt(Consumer<TryStmt> action)310 public void ifTryStmt(Consumer<TryStmt> action) { 311 action.accept(this); 312 } 313 314 @Override 315 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") toTryStmt()316 public Optional<TryStmt> toTryStmt() { 317 return Optional.of(this); 318 } 319 } 320