blob: d2e22d9dd7846c11af2ff50a444d4ece695b726d [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.devtools.build.lib.syntax;
16
17import com.google.common.annotations.VisibleForTesting;
18import com.google.devtools.build.lib.events.Location;
19
20import java.io.Serializable;
21
22/**
23 * Root class for nodes in the Abstract Syntax Tree of the Build language.
brandjon540aac62017-06-12 23:08:09 +020024 *
25 * The standard {@link Object#equals} and {@link Object#hashCode} methods are not supported. This is
26 * because their implementation would require traversing the entire tree in the worst case, and we
27 * don't want this kind of cost to occur implicitly.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010028 */
29public abstract class ASTNode implements Serializable {
30
31 private Location location;
32
33 protected ASTNode() {}
34
Florian Weikert90a15962015-09-11 13:43:10 +000035 /**
36 * Returns whether this node represents a new scope, e.g. a function call.
37 */
38 protected boolean isNewScope() {
39 return false;
40 }
41
Janak Ramakrishnan3745c902016-05-11 08:12:10 +000042 /** Returns an exception which should be thrown instead of the original one. */
43 protected final EvalException maybeTransformException(EvalException original) {
Florian Weikert90a15962015-09-11 13:43:10 +000044 // If there is already a non-empty stack trace, we only add this node iff it describes a
45 // new scope (e.g. FuncallExpression).
Florian Weikert4b67d4f2015-09-14 13:35:34 +000046 if (original instanceof EvalExceptionWithStackTrace) {
Florian Weikert90a15962015-09-11 13:43:10 +000047 EvalExceptionWithStackTrace real = (EvalExceptionWithStackTrace) original;
Florian Weikert4b67d4f2015-09-14 13:35:34 +000048 if (isNewScope()) {
49 real.registerNode(this);
50 }
Florian Weikert90a15962015-09-11 13:43:10 +000051 return real;
52 }
53
Janak Ramakrishnan3745c902016-05-11 08:12:10 +000054 if (original.canBeAddedToStackTrace()) {
55 return new EvalExceptionWithStackTrace(original, this);
56 } else {
57 return original;
Florian Weikert90a15962015-09-11 13:43:10 +000058 }
Florian Weikert90a15962015-09-11 13:43:10 +000059 }
60
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010061 @VisibleForTesting // productionVisibility = Visibility.PACKAGE_PRIVATE
62 public void setLocation(Location location) {
63 this.location = location;
64 }
65
66 public Location getLocation() {
67 return location;
68 }
69
Francois-Rene Rideauedf7bdb2015-03-02 17:12:45 +000070 /** @return the same node with its location set, in a slightly more fluent style */
71 public static <NODE extends ASTNode> NODE setLocation(Location location, NODE node) {
72 node.setLocation(location);
73 return node;
74 }
75
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010076 /**
77 * Print the syntax node in a form useful for debugging. The output is not
78 * precisely specified, and should not be used by pretty-printing routines.
79 */
80 @Override
81 public abstract String toString();
82
83 @Override
84 public int hashCode() {
brandjon540aac62017-06-12 23:08:09 +020085 throw new UnsupportedOperationException();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010086 }
87
88 @Override
89 public boolean equals(Object that) {
90 throw new UnsupportedOperationException();
91 }
92
93 /**
94 * Implements the double dispatch by calling into the node specific
95 * <code>visit</code> method of the {@link SyntaxTreeVisitor}
96 *
97 * @param visitor the {@link SyntaxTreeVisitor} instance to dispatch to.
98 */
99 public abstract void accept(SyntaxTreeVisitor visitor);
100
101}