1 /* 2 * Copyright (c) 2010, 2016, 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 /** 33 * IR representation of a property access (period operator.) 34 */ 35 @Immutable 36 public final class AccessNode extends BaseNode { 37 private static final long serialVersionUID = 1L; 38 39 /** Property name. */ 40 private final String property; 41 42 /** 43 * Constructor 44 * 45 * @param token token 46 * @param finish finish 47 * @param base base node 48 * @param property property 49 */ AccessNode(final long token, final int finish, final Expression base, final String property)50 public AccessNode(final long token, final int finish, final Expression base, final String property) { 51 super(token, finish, base, false, false); 52 this.property = property; 53 } 54 AccessNode(final AccessNode accessNode, final Expression base, final String property, final boolean isFunction, final Type type, final int id, final boolean isSuper)55 private AccessNode(final AccessNode accessNode, final Expression base, final String property, final boolean isFunction, 56 final Type type, final int id, final boolean isSuper) { 57 super(accessNode, base, isFunction, type, id, isSuper); 58 this.property = property; 59 } 60 61 /** 62 * Assist in IR navigation. 63 * @param visitor IR navigating visitor. 64 */ 65 @Override accept(final NodeVisitor<? extends LexicalContext> visitor)66 public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { 67 if (visitor.enterAccessNode(this)) { 68 return visitor.leaveAccessNode( 69 setBase((Expression)base.accept(visitor))); 70 } 71 return this; 72 } 73 74 @Override toString(final StringBuilder sb, final boolean printType)75 public void toString(final StringBuilder sb, final boolean printType) { 76 final boolean needsParen = tokenType().needsParens(getBase().tokenType(), true); 77 78 if (printType) { 79 optimisticTypeToString(sb); 80 } 81 82 if (needsParen) { 83 sb.append('('); 84 } 85 86 base.toString(sb, printType); 87 88 if (needsParen) { 89 sb.append(')'); 90 } 91 sb.append('.'); 92 93 sb.append(property); 94 } 95 96 /** 97 * Get the property name 98 * 99 * @return the property name 100 */ getProperty()101 public String getProperty() { 102 return property; 103 } 104 setBase(final Expression base)105 private AccessNode setBase(final Expression base) { 106 if (this.base == base) { 107 return this; 108 } 109 return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper()); 110 } 111 112 @Override setType(final Type type)113 public AccessNode setType(final Type type) { 114 if (this.type == type) { 115 return this; 116 } 117 return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper()); 118 } 119 120 @Override setProgramPoint(final int programPoint)121 public AccessNode setProgramPoint(final int programPoint) { 122 if (this.programPoint == programPoint) { 123 return this; 124 } 125 return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper()); 126 } 127 128 @Override setIsFunction()129 public AccessNode setIsFunction() { 130 if (isFunction()) { 131 return this; 132 } 133 return new AccessNode(this, base, property, true, type, programPoint, isSuper()); 134 } 135 136 @Override setIsSuper()137 public AccessNode setIsSuper() { 138 if (isSuper()) { 139 return this; 140 } 141 return new AccessNode(this, base, property, isFunction(), type, programPoint, true); 142 } 143 } 144