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 import jdk.nashorn.internal.ir.annotations.Immutable; 30 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 31 /** 32 * IR representation of an indexed access (brackets operator.) 33 */ 34 @Immutable 35 public final class IndexNode extends BaseNode { 36 private static final long serialVersionUID = 1L; 37 38 /** Property index. */ 39 private final Expression index; 40 41 /** 42 * Constructors 43 * 44 * @param token token 45 * @param finish finish 46 * @param base base node for access 47 * @param index index for access 48 */ 49 public IndexNode(final long token, final int finish, final Expression base, final Expression index) { 50 super(token, finish, base, false, false); 51 this.index = index; 52 } 53 54 private IndexNode(final IndexNode indexNode, final Expression base, final Expression index, final boolean isFunction, 55 final Type type, final int programPoint, final boolean isSuper) { 56 super(indexNode, base, isFunction, type, programPoint, isSuper); 57 this.index = index; 58 } 59 60 @Override 61 public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { 62 if (visitor.enterIndexNode(this)) { 63 return visitor.leaveIndexNode( 64 setBase((Expression)base.accept(visitor)). 65 setIndex((Expression)index.accept(visitor))); 66 } 67 return this; 68 } 69 70 @Override 71 public void toString(final StringBuilder sb, final boolean printType) { 72 final boolean needsParen = tokenType().needsParens(base.tokenType(), true); 73 74 if (needsParen) { 75 sb.append('('); 76 } 77 78 if (printType) { 79 optimisticTypeToString(sb); 80 } 81 82 base.toString(sb, printType); 83 84 if (needsParen) { 85 sb.append(')'); 86 } 87 88 sb.append('['); 89 index.toString(sb, printType); 90 sb.append(']'); 91 } 92 93 /** 94 * Get the index expression for this IndexNode 95 * @return the index 96 */ 97 public Expression getIndex() { 98 return index; 99 } 100 101 private IndexNode setBase(final Expression base) { 102 if (this.base == base) { 103 return this; 104 } 105 return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper()); 106 } 107 108 /** 109 * Set the index expression for this node 110 * @param index new index expression 111 * @return a node equivalent to this one except for the requested change. 112 */ 113 public IndexNode setIndex(final Expression index) { 114 if(this.index == index) { 115 return this; 116 } 117 return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper()); 118 } 119 120 @Override 121 public IndexNode setType(final Type type) { 122 if (this.type == type) { 123 return this; 124 } 125 return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper()); 126 } 127 128 @Override 129 public IndexNode setIsFunction() { 130 if (isFunction()) { 131 return this; 132 } 133 return new IndexNode(this, base, index, true, type, programPoint, isSuper()); 134 } 135 136 @Override 137 public IndexNode setProgramPoint(final int programPoint) { 138 if (this.programPoint == programPoint) { 139 return this; 140 } 141 return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper()); 142 } 143 144 @Override 145 public IndexNode setIsSuper() { 146 if (isSuper()) { 147 return this; 148 } 149 return new IndexNode(this, base, index, isFunction(), type, programPoint, true); 150 } 151 }