View Javadoc
1   package net.sourceforge.jenesis4java.impl;
2   
3   /*
4    * #%L
5    * Jenesis 4 Java Code Generator
6    * %%
7    * Copyright (C) 2000 - 2015 jenesis4java
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Lesser Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * #L%
23   */
24  
25  /**
26   * Copyright (C) 2008, 2010 Richard van Nieuwenhoven - ritchie [at] gmx [dot] at
27   * Copyright (C) 2000, 2001 Paul Cody Johnston - pcj@inxar.org <br>
28   * This file is part of Jenesis4java. Jenesis4java is free software: you can
29   * redistribute it and/or modify it under the terms of the GNU Lesser General
30   * Public License as published by the Free Software Foundation, either version 3
31   * of the License, or (at your option) any later version.<br>
32   * Jenesis4java is distributed in the hope that it will be useful, but WITHOUT
33   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
34   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
35   * details.<br>
36   * You should have received a copy of the GNU Lesser General Public License
37   * along with Jenesis4java. If not, see <http://www.gnu.org/licenses/>.
38   */
39  import java.util.ArrayList;
40  import java.util.List;
41  
42  import net.sourceforge.jenesis4java.Assign;
43  import net.sourceforge.jenesis4java.Catch;
44  import net.sourceforge.jenesis4java.CodeWriter;
45  import net.sourceforge.jenesis4java.Expression;
46  import net.sourceforge.jenesis4java.Finally;
47  import net.sourceforge.jenesis4java.ReplacingVisitor;
48  import net.sourceforge.jenesis4java.Try;
49  import net.sourceforge.jenesis4java.TryResource;
50  import net.sourceforge.jenesis4java.Type;
51  import net.sourceforge.jenesis4java.impl.util.ListTypeSelector;
52  import net.sourceforge.jenesis4java.impl.util.VisitorUtils;
53  
54  /**
55   * Allows to create try statements (the standard as well as the so-called
56   * try-with-resources variant).
57   */
58  class MTry extends MStatement.BlockStatement implements Try {
59  
60      public static class MTryResource extends MVM.MCodeable implements TryResource {
61  
62          private Type type;
63  
64          private boolean isFinal;
65  
66          private Assign assign;
67  
68          public MTryResource(MVM vm, Type type, String name, Expression expr) {
69              super(vm);
70              this.type = type;
71              assign = new MExpression.MAssign(this.vm, Assign.S, new MExpression.MVariable(this.vm, name), expr);
72          }
73  
74          @Override
75          public CodeWriter toCode(CodeWriter out) {
76              super.toCode(out);
77              if (isFinal) {
78                  out.write("final").space();
79              }
80              out.write(type).space();
81              out.write(assign);
82              return out;
83          }
84  
85          @Override
86          public boolean isFinal() {
87              return isFinal;
88          }
89  
90          @Override
91          public TryResource isFinal(boolean value) {
92              isFinal = value;
93              return this;
94          }
95  
96          @Override
97          public void visit(ReplacingVisitor visitor) {
98              super.visit(visitor);
99              type = VisitorUtils.visit(type, this, visitor);
100             assign = VisitorUtils.visit(assign, this, visitor);
101         }
102     }
103 
104     private List<Catch> vcc;
105 
106     private List<MTryResource> resources;
107 
108     private Finally finallyClause;
109 
110     MTry(MVM vm) {
111         super(vm);
112         vcc = new ArrayList<>();
113     }
114 
115     @Override
116     public List<Catch> getCatches() {
117         return ListTypeSelector.select(vcc);
118     }
119 
120     @Override
121     public Finally getFinally() {
122         if (finallyClause == null) {
123             finallyClause = new MFinally(vm);
124         }
125         return finallyClause;
126     }
127 
128     @Override
129     public Catch newCatch(Type type, String name) {
130         Catch cc = new MCatch(vm, type, name);
131         vcc.add(cc);
132         return cc;
133     }
134 
135     @Override
136     public TryResource newResource(Type type, String name, Expression expr) {
137         if (resources == null) {
138             resources = new ArrayList<>(1);
139         }
140         MTryResource resource = new MTryResource(vm, type, name, expr);
141         resources.add(resource);
142         return resource;
143     }
144 
145     @Override
146     public CodeWriter toCode(CodeWriter out) {
147         super.toCode(out);
148         out.write("try");
149         writeResources(out);
150         writeBlock(out, vm.getStyle("try"));
151         writeCatches(vcc, out);
152         out.write(finallyClause);
153         return out;
154     }
155 
156     private void writeResources(CodeWriter out) {
157         if (resources == null) {
158             return;
159         }
160         int columnNumber = out.write("(").getColumnNumber();
161         boolean isFirst = true;
162         for (MTryResource resource : resources) {
163             if (isFirst) {
164                 isFirst = false;
165             } else {
166                 out.write(";").newLine();
167                 for (int i = 0; i < columnNumber; i++) {
168                     out.space();
169                 }
170             }
171             resource.toCode(out);
172         }
173         out.write(")");
174     }
175 
176     @Override
177     public void visit(ReplacingVisitor visitor) {
178         super.visit(visitor);
179         if (resources != null) {
180             VisitorUtils.visit(resources, this, visitor);
181         }
182         VisitorUtils.visit(vcc, this, visitor);
183         finallyClause = VisitorUtils.visit(finallyClause, this, visitor);
184     }
185 
186     // utility method
187     private CodeWriter writeCatches(List<Catch> v, CodeWriter out) {
188         for (Catch catch1 : v) {
189             out.write(catch1);
190         }
191         return out;
192     }
193 }