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