1 | /* |
---|---|
2 | * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser. |
3 | * Copyright (C) 2011, 2013-2020 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 | |
106 | public TryStmt() { |
107 | this(null, new NodeList<>(), new BlockStmt(), new NodeList<>(), null); |
108 | } |
109 | |
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 |
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") |
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") |
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") |
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") |
145 | public NodeList<CatchClause> getCatchClauses() { |
146 | return catchClauses; |
147 | } |
148 | |
149 | @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") |
150 | public Optional<BlockStmt> getFinallyBlock() { |
151 | return Optional.ofNullable(finallyBlock); |
152 | } |
153 | |
154 | @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") |
155 | public BlockStmt getTryBlock() { |
156 | return tryBlock; |
157 | } |
158 | |
159 | @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") |
160 | public NodeList<Expression> getResources() { |
161 | return resources; |
162 | } |
163 | |
164 | @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") |
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") |
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") |
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") |
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") |
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") |
246 | public TryStmt removeFinallyBlock() { |
247 | return setFinallyBlock((BlockStmt) null); |
248 | } |
249 | |
250 | @Override |
251 | @Generated("com.github.javaparser.generator.core.node.CloneGenerator") |
252 | public TryStmt clone() { |
253 | return (TryStmt) accept(new CloneVisitor(), null); |
254 | } |
255 | |
256 | @Override |
257 | @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator") |
258 | public TryStmtMetaModel getMetaModel() { |
259 | return JavaParserMetaModel.tryStmtMetaModel; |
260 | } |
261 | |
262 | @Override |
263 | @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator") |
264 | public boolean replace(Node node, Node replacementNode) { |
265 | if (node == null) |
266 | return false; |
267 | for (int i = 0; i < catchClauses.size(); i++) { |
268 | if (catchClauses.get(i) == node) { |
269 | catchClauses.set(i, (CatchClause) replacementNode); |
270 | return true; |
271 | } |
272 | } |
273 | if (finallyBlock != null) { |
274 | if (node == finallyBlock) { |
275 | setFinallyBlock((BlockStmt) replacementNode); |
276 | return true; |
277 | } |
278 | } |
279 | for (int i = 0; i < resources.size(); i++) { |
280 | if (resources.get(i) == node) { |
281 | resources.set(i, (Expression) replacementNode); |
282 | return true; |
283 | } |
284 | } |
285 | if (node == tryBlock) { |
286 | setTryBlock((BlockStmt) replacementNode); |
287 | return true; |
288 | } |
289 | return super.replace(node, replacementNode); |
290 | } |
291 | |
292 | @Override |
293 | @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") |
294 | public boolean isTryStmt() { |
295 | return true; |
296 | } |
297 | |
298 | @Override |
299 | @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") |
300 | public TryStmt asTryStmt() { |
301 | return this; |
302 | } |
303 | |
304 | @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") |
305 | public void ifTryStmt(Consumer<TryStmt> action) { |
306 | action.accept(this); |
307 | } |
308 | |
309 | @Override |
310 | @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") |
311 | public Optional<TryStmt> toTryStmt() { |
312 | return Optional.of(this); |
313 | } |
314 | } |
315 |
Members