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 static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
29 
30 import jdk.nashorn.internal.codegen.types.Type;
31 import jdk.nashorn.internal.ir.annotations.Immutable;
32 import jdk.nashorn.internal.parser.TokenType;
33 
34 /**
35  * IR base for accessing/indexing nodes.
36  *
37  * @see AccessNode
38  * @see IndexNode
39  */
40 @Immutable
41 public abstract class BaseNode extends Expression implements FunctionCall, Optimistic {
42     private static final long serialVersionUID = 1L;
43 
44     /** Base Node. */
45     protected final Expression base;
46 
47     private final boolean isFunction;
48 
49     /** Callsite type for this node, if overridden optimistically or conservatively depending on coercion */
50     protected final Type type;
51 
52     /** Program point id */
53     protected final int programPoint;
54 
55     /** Super property access. */
56     private final boolean isSuper;
57 
58     /**
59      * Constructor
60      *
61      * @param token  token
62      * @param finish finish
63      * @param base   base node
64      * @param isFunction is this a function
65      * @param isSuper is this a super property access
66      */
BaseNode(final long token, final int finish, final Expression base, final boolean isFunction, final boolean isSuper)67     public BaseNode(final long token, final int finish, final Expression base, final boolean isFunction, final boolean isSuper) {
68         super(token, base.getStart(), finish);
69         this.base           = base;
70         this.isFunction     = isFunction;
71         this.type = null;
72         this.programPoint   = INVALID_PROGRAM_POINT;
73         this.isSuper        = isSuper;
74     }
75 
76     /**
77      * Copy constructor for immutable nodes
78      * @param baseNode node to inherit from
79      * @param base base
80      * @param isFunction is this a function
81      * @param callSiteType  the callsite type for this base node, either optimistic or conservative
82      * @param programPoint  program point id
83      * @param isSuper is this a super property access
84      */
BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction, final Type callSiteType, final int programPoint, final boolean isSuper)85     protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction, final Type callSiteType, final int programPoint, final boolean isSuper) {
86         super(baseNode);
87         this.base           = base;
88         this.isFunction     = isFunction;
89         this.type = callSiteType;
90         this.programPoint   = programPoint;
91         this.isSuper        = isSuper;
92     }
93 
94     /**
95      * Get the base node for this access
96      * @return the base node
97      */
getBase()98     public Expression getBase() {
99         return base;
100     }
101 
102     @Override
isFunction()103     public boolean isFunction() {
104         return isFunction;
105     }
106 
107     @Override
getType()108     public Type getType() {
109         return type == null ? getMostPessimisticType() : type;
110     }
111 
112     @Override
getProgramPoint()113     public int getProgramPoint() {
114         return programPoint;
115     }
116 
117     @Override
getMostOptimisticType()118     public Type getMostOptimisticType() {
119         return Type.INT;
120     }
121 
122     @Override
getMostPessimisticType()123     public Type getMostPessimisticType() {
124         return Type.OBJECT;
125     }
126 
127     @Override
canBeOptimistic()128     public boolean canBeOptimistic() {
129         return true;
130     }
131 
132     /**
133      * Return true if this node represents an index operation normally represented as {@link IndexNode}.
134      * @return true if an index access.
135      */
isIndex()136     public boolean isIndex() {
137         return isTokenType(TokenType.LBRACKET);
138     }
139 
140     /**
141      * Mark this node as being the callee operand of a {@link CallNode}.
142      * @return a base node identical to this one in all aspects except with its function flag set.
143      */
setIsFunction()144     public abstract BaseNode setIsFunction();
145 
146     /**
147      * @return {@code true} if a SuperProperty access.
148      */
isSuper()149     public boolean isSuper() {
150         return isSuper;
151     }
152 
153     /**
154      * Mark this node as being a SuperProperty access.
155      *
156      * @return  a base node identical to this one in all aspects except with its super flag set.
157      */
setIsSuper()158     public abstract BaseNode setIsSuper();
159 }
160