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 of an object literal property. 33 */ 34 @Immutable 35 public final class PropertyNode extends Node { 36 private static final long serialVersionUID = 1L; 37 38 /** Property key. */ 39 private final Expression key; 40 41 /** Property value. */ 42 private final Expression value; 43 44 /** Property getter. */ 45 private final FunctionNode getter; 46 47 /** Property getter. */ 48 private final FunctionNode setter; 49 50 /** static property flag */ 51 private final boolean isStatic; 52 53 /** Computed property flag */ 54 private final boolean computed; 55 56 /** 57 * Constructor 58 * 59 * @param token token 60 * @param finish finish 61 * @param key the key of this property 62 * @param value the value of this property 63 * @param getter getter function body 64 * @param setter setter function body 65 * @param isStatic is this a static property? 66 * @param computed is this a computed property? 67 */ 68 public PropertyNode(final long token, final int finish, final Expression key, final Expression value, final FunctionNode getter, final FunctionNode setter, final boolean isStatic, final boolean computed) { 69 super(token, finish); 70 this.key = key; 71 this.value = value; 72 this.getter = getter; 73 this.setter = setter; 74 this.isStatic = isStatic; 75 this.computed = computed; 76 } 77 78 private PropertyNode(final PropertyNode propertyNode, final Expression key, final Expression value, final FunctionNode getter, final FunctionNode setter, final boolean isStatic, final boolean computed) { 79 super(propertyNode); 80 this.key = key; 81 this.value = value; 82 this.getter = getter; 83 this.setter = setter; 84 this.isStatic = isStatic; 85 this.computed = computed; 86 } 87 88 /** 89 * Get the name of the property key 90 * @return key name 91 */ 92 public String getKeyName() { 93 return key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : null; 94 } 95 96 @Override 97 public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { 98 if (visitor.enterPropertyNode(this)) { 99 return visitor.leavePropertyNode( 100 setKey((Expression) key.accept(visitor)). 101 setValue(value == null ? null : (Expression)value.accept(visitor)). 102 setGetter(getter == null ? null : (FunctionNode)getter.accept(visitor)). 103 setSetter(setter == null ? null : (FunctionNode)setter.accept(visitor))); 104 } 105 106 return this; 107 } 108 109 @Override 110 public void toString(final StringBuilder sb, final boolean printType) { 111 if (value instanceof FunctionNode && ((FunctionNode)value).getIdent() != null) { 112 value.toString(sb); 113 } 114 115 if (value != null) { 116 ((Node)key).toString(sb, printType); 117 sb.append(": "); 118 value.toString(sb, printType); 119 } 120 121 if (getter != null) { 122 sb.append(' '); 123 getter.toString(sb, printType); 124 } 125 126 if (setter != null) { 127 sb.append(' '); 128 setter.toString(sb, printType); 129 } 130 } 131 132 /** 133 * Get the getter for this property 134 * @return getter or null if none exists 135 */ 136 public FunctionNode getGetter() { 137 return getter; 138 } 139 140 /** 141 * Set the getter of this property, null if none 142 * @param getter getter 143 * @return same node or new node if state changed 144 */ 145 public PropertyNode setGetter(final FunctionNode getter) { 146 if (this.getter == getter) { 147 return this; 148 } 149 return new PropertyNode(this, key, value, getter, setter, isStatic, computed); 150 } 151 152 /** 153 * Return the key for this property node 154 * @return the key 155 */ 156 public Expression getKey() { 157 return key; 158 } 159 160 private PropertyNode setKey(final Expression key) { 161 if (this.key == key) { 162 return this; 163 } 164 return new PropertyNode(this, key, value, getter, setter, isStatic, computed); 165 } 166 167 /** 168 * Get the setter for this property 169 * @return setter or null if none exists 170 */ 171 public FunctionNode getSetter() { 172 return setter; 173 } 174 175 /** 176 * Set the setter for this property, null if none 177 * @param setter setter 178 * @return same node or new node if state changed 179 */ 180 public PropertyNode setSetter(final FunctionNode setter) { 181 if (this.setter == setter) { 182 return this; 183 } 184 return new PropertyNode(this, key, value, getter, setter, isStatic, computed); 185 } 186 187 /** 188 * Get the value of this property 189 * @return property value 190 */ 191 public Expression getValue() { 192 return value; 193 } 194 195 /** 196 * Set the value of this property 197 * @param value new value 198 * @return same node or new node if state changed 199 */ 200 public PropertyNode setValue(final Expression value) { 201 if (this.value == value) { 202 return this; 203 } 204 return new PropertyNode(this, key, value, getter, setter, isStatic, computed); 205 } 206 207 /** 208 * Returns true if this is a static property. 209 * 210 * @return true if static flag is set 211 */ 212 public boolean isStatic() { 213 return isStatic; 214 } 215 216 /** 217 * Returns true if this is a computed property. 218 * 219 * @return true if the computed flag is set 220 */ 221 public boolean isComputed() { 222 return computed; 223 } 224 }