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.codegen.types.Type;
29  
30  /**
31   * Common superclass for all expression nodes. Expression nodes can have
32   * an associated symbol as well as a type.
33   *
34   */
35  public abstract class Expression extends Node {
36      private Symbol symbol;
37  
38      Expression(long token, int start, int finish) {
39          super(token, start, finish);
40      }
41  
42      Expression(long token, int finish) {
43          super(token, finish);
44      }
45  
46      Expression(Expression expr) {
47          super(expr);
48          this.symbol = expr.symbol;
49      }
50  
51      /**
52       * Return the Symbol the compiler has assigned to this Node. The symbol
53       * is the place where it's expression value is stored after evaluation
54       *
55       * @return the symbol
56       */
57      public Symbol getSymbol() {
58          return symbol;
59      }
60  
61      /**
62       * Assign a symbol to this node. See {@link Expression#getSymbol()} for explanation
63       * of what a symbol is
64       *
65       * @param lc lexical context
66       * @param symbol the symbol
67       * @return new node
68       */
69      public Expression setSymbol(final LexicalContext lc, final Symbol symbol) {
70          if (this.symbol == symbol) {
71              return this;
72          }
73          final Expression newExpr = (Expression)clone();
74          newExpr.symbol = symbol;
75          return newExpr;
76      }
77  
78      /**
79       * Check if the expression has a type. The default behavior is to go into the symbol
80       * and check the symbol type, but there may be overrides, for example in
81       * getters that require a different type than the internal representation
82       *
83       * @return true if a type exists
84       */
85      public boolean hasType() {
86          return getSymbol() != null;
87      }
88  
89      /**
90       * Returns the type of the expression. Typically this is the symbol type. No types
91       * are stored in the expression itself, unless it implements TypeOverride.
92       *
93       * @return the type of the node.
94       */
95      public Type getType() {
96          assert hasType() : this + " has no type";
97          return symbol.getSymbolType();
98      }
99  
100     /**
101      * Returns {@code true} if this expression depends exclusively on state that is constant
102      * or local to the currently running function and thus inaccessible to other functions.
103      * This implies that a local expression must not call any other functions (neither directly
104      * nor implicitly through a getter, setter, or object-to-primitive type conversion).
105      *
106      * @return true if this expression does not depend on state shared with other functions.
107      */
108     public boolean isLocal() {
109         return false;
110     }
111 }