View Javadoc
1   /*
2    * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package jdk.nashorn.internal.ir;
27  
28  import jdk.nashorn.internal.ir.annotations.Immutable;
29  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
30  
31  /**
32   * IR representation for {@code with} statements.
33   */
34  @Immutable
35  public final class WithNode extends LexicalContextStatement {
36     /** This expression. */
37      private final Expression expression;
38  
39      /** Statements. */
40      private final Block body;
41  
42      /**
43       * Constructor
44       *
45       * @param lineNumber line number
46       * @param token      token
47       * @param finish     finish
48       */
49      public WithNode(final int lineNumber, final long token, final int finish) {
50          super(lineNumber, token, finish);
51          this.expression = null;
52          this.body       = null;
53      }
54  
55      private WithNode(final WithNode node, final Expression expression, final Block body) {
56          super(node);
57          this.expression = expression;
58          this.body       = body;
59      }
60  
61      /**
62       * Assist in IR navigation.
63       *
64       * @param visitor IR navigating visitor.
65       */
66      @Override
67      public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
68          if (visitor.enterWithNode(this)) {
69               return visitor.leaveWithNode(
70                  setExpression(lc, (Expression)expression.accept(visitor)).
71                  setBody(lc, (Block)body.accept(visitor)));
72          }
73          return this;
74      }
75  
76      @Override
77      public boolean isTerminal() {
78          return body.isTerminal();
79      }
80  
81      @Override
82      public void toString(final StringBuilder sb) {
83          sb.append("with (");
84          expression.toString(sb);
85          sb.append(')');
86      }
87  
88      /**
89       * Get the body of this WithNode
90       * @return the body
91       */
92      public Block getBody() {
93          return body;
94      }
95  
96      /**
97       * Reset the body of this with node
98       * @param lc lexical context
99       * @param body new body
100      * @return new or same withnode
101      */
102     public WithNode setBody(final LexicalContext lc, final Block body) {
103         if (this.body == body) {
104             return this;
105         }
106         return Node.replaceInLexicalContext(lc, this, new WithNode(this, expression, body));
107     }
108 
109     /**
110      * Get the expression of this WithNode
111      * @return the expression
112      */
113     public Expression getExpression() {
114         return expression;
115     }
116 
117     /**
118      * Reset the expression of this with node
119      * @param lc lexical context
120      * @param expression new expression
121      * @return new or same withnode
122      */
123     public WithNode setExpression(final LexicalContext lc, final Expression expression) {
124         if (this.expression == expression) {
125             return this;
126         }
127         return Node.replaceInLexicalContext(lc, this, new WithNode(this, expression, body));
128     }
129 }
130