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