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 a labeled statement.
33   */
34  @Immutable
35  public final class LabelNode extends LexicalContextStatement {
36      /** Label ident. */
37      private final IdentNode label;
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       * @param label      label identifier
49       * @param body       body of label node
50       */
51      public LabelNode(final int lineNumber, final long token, final int finish, final IdentNode label, final Block body) {
52          super(lineNumber, token, finish);
53  
54          this.label = label;
55          this.body  = body;
56      }
57  
58      private LabelNode(final LabelNode labelNode, final IdentNode label, final Block body) {
59          super(labelNode);
60          this.label = label;
61          this.body  = body;
62      }
63  
64      @Override
65      public boolean isTerminal() {
66          return body.isTerminal();
67      }
68  
69      @Override
70      public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
71          if (visitor.enterLabelNode(this)) {
72              return visitor.leaveLabelNode(
73                  setLabel(lc, (IdentNode)label.accept(visitor)).
74                  setBody(lc, (Block)body.accept(visitor)));
75          }
76  
77          return this;
78      }
79  
80      @Override
81      public void toString(final StringBuilder sb) {
82          label.toString(sb);
83          sb.append(':');
84      }
85  
86      /**
87       * Get the body of the node
88       * @return the body
89       */
90      public Block getBody() {
91          return body;
92      }
93  
94      /**
95       * Reset the body of the node
96       * @param lc lexical context
97       * @param body new body
98       * @return new for node if changed or existing if not
99       */
100     public LabelNode setBody(final LexicalContext lc, final Block body) {
101         if (this.body == body) {
102             return this;
103         }
104         return Node.replaceInLexicalContext(lc, this, new LabelNode(this, label, body));
105     }
106 
107     /**
108      * Get the identifier representing the label name
109      * @return the label
110      */
111     public IdentNode getLabel() {
112         return label;
113     }
114 
115     private LabelNode setLabel(final LexicalContext lc, final IdentNode label) {
116         if (this.label == label) {
117             return this;
118         }
119         return Node.replaceInLexicalContext(lc, this, new LabelNode(this, label, body));
120     }
121 
122 }