AccessNode.java revision 1668:bafd733be429
1285242Sachim/*
2285242Sachim * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
3285242Sachim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4285242Sachim *
5285242Sachim * This code is free software; you can redistribute it and/or modify it
6285242Sachim * under the terms of the GNU General Public License version 2 only, as
7285242Sachim * published by the Free Software Foundation.  Oracle designates this
8285242Sachim * particular file as subject to the "Classpath" exception as provided
9285242Sachim * by Oracle in the LICENSE file that accompanied this code.
10285242Sachim *
11285242Sachim * This code is distributed in the hope that it will be useful, but WITHOUT
12285242Sachim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13285242Sachim * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14285242Sachim * version 2 for more details (a copy is included in the LICENSE file that
15285242Sachim * accompanied this code).
16285242Sachim *
17285242Sachim * You should have received a copy of the GNU General Public License version
18285242Sachim * 2 along with this work; if not, write to the Free Software Foundation,
19285242Sachim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20285242Sachim *
21285242Sachim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22285242Sachim * or visit www.oracle.com if you need additional information or have any
23285242Sachim * questions.
24285242Sachim */
25285242Sachim
26285242Sachimpackage jdk.nashorn.internal.ir;
27285242Sachim
28285242Sachimimport jdk.nashorn.internal.codegen.types.Type;
29285242Sachimimport jdk.nashorn.internal.ir.annotations.Immutable;
30285242Sachimimport jdk.nashorn.internal.ir.visitor.NodeVisitor;
31285242Sachim
32285242Sachim/**
33285242Sachim * IR representation of a property access (period operator.)
34285242Sachim */
35285242Sachim@Immutable
36285242Sachimpublic final class AccessNode extends BaseNode {
37285242Sachim    private static final long serialVersionUID = 1L;
38285242Sachim
39285242Sachim    /** Property name. */
40285242Sachim    private final String property;
41285242Sachim
42285242Sachim    /**
43285242Sachim     * Constructor
44285242Sachim     *
45285242Sachim     * @param token     token
46285242Sachim     * @param finish    finish
47285242Sachim     * @param base      base node
48285242Sachim     * @param property  property
49285242Sachim     */
50285242Sachim    public AccessNode(final long token, final int finish, final Expression base, final String property) {
51285242Sachim        super(token, finish, base, false, false);
52285242Sachim        this.property = property;
53285242Sachim    }
54285242Sachim
55285242Sachim    private AccessNode(final AccessNode accessNode, final Expression base, final String property, final boolean isFunction,
56285242Sachim                       final Type type, final int id, final boolean isSuper) {
57285242Sachim        super(accessNode, base, isFunction, type, id, isSuper);
58285242Sachim        this.property = property;
59285242Sachim    }
60285242Sachim
61285242Sachim    /**
62285242Sachim     * Assist in IR navigation.
63285242Sachim     * @param visitor IR navigating visitor.
64285242Sachim     */
65285242Sachim    @Override
66285242Sachim    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
67285242Sachim        if (visitor.enterAccessNode(this)) {
68285242Sachim            return visitor.leaveAccessNode(
69285242Sachim                setBase((Expression)base.accept(visitor)));
70285242Sachim        }
71285242Sachim        return this;
72285242Sachim    }
73285242Sachim
74285242Sachim    @Override
75285242Sachim    public void toString(final StringBuilder sb, final boolean printType) {
76285242Sachim        final boolean needsParen = tokenType().needsParens(getBase().tokenType(), true);
77285242Sachim
78285242Sachim        if (printType) {
79285242Sachim            optimisticTypeToString(sb);
80285242Sachim        }
81285242Sachim
82285242Sachim        if (needsParen) {
83285242Sachim            sb.append('(');
84285242Sachim        }
85285242Sachim
86285242Sachim        base.toString(sb, printType);
87285242Sachim
88285242Sachim        if (needsParen) {
89285242Sachim            sb.append(')');
90285242Sachim        }
91285242Sachim        sb.append('.');
92285242Sachim
93285242Sachim        sb.append(property);
94285242Sachim    }
95285242Sachim
96285242Sachim    /**
97285242Sachim     * Get the property name
98285242Sachim     *
99285242Sachim     * @return the property name
100285242Sachim     */
101285242Sachim    public String getProperty() {
102285242Sachim        return property;
103285242Sachim    }
104285242Sachim
105285242Sachim    private AccessNode setBase(final Expression base) {
106285242Sachim        if (this.base == base) {
107285242Sachim            return this;
108285242Sachim        }
109285242Sachim        return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper());
110285242Sachim    }
111285242Sachim
112285242Sachim    @Override
113285242Sachim    public AccessNode setType(final Type type) {
114285242Sachim        if (this.type == type) {
115285242Sachim            return this;
116285242Sachim        }
117285242Sachim        return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper());
118285242Sachim    }
119285242Sachim
120285242Sachim    @Override
121285242Sachim    public AccessNode setProgramPoint(final int programPoint) {
122285242Sachim        if (this.programPoint == programPoint) {
123285242Sachim            return this;
124285242Sachim        }
125285242Sachim        return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper());
126285242Sachim    }
127285242Sachim
128285242Sachim    @Override
129285242Sachim    public AccessNode setIsFunction() {
130285242Sachim        if (isFunction()) {
131285242Sachim            return this;
132285242Sachim        }
133285242Sachim        return new AccessNode(this, base, property, true, type, programPoint, isSuper());
134285242Sachim    }
135285242Sachim
136285242Sachim    @Override
137285242Sachim    public AccessNode setIsSuper() {
138285242Sachim        if (isSuper()) {
139285242Sachim            return this;
140285242Sachim        }
141285242Sachim        return new AccessNode(this, base, property, isFunction(), type, programPoint, true);
142285242Sachim    }
143285242Sachim}
144285242Sachim