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