blob: 3361add166897a4b9d4edd08fb7d49d3b7d03849 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +00002//
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.
14package com.google.devtools.build.lib.syntax;
15
brandjone2ffd5d2017-06-27 18:14:54 +020016import java.io.IOException;
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000017import javax.annotation.Nullable;
18
19/**
20 * Syntax node for a Parameter in a function (or lambda) definition; it's a subclass of Argument,
21 * and contrasts with the class Argument.Passed of arguments in a function call.
22 *
23 * <p>There are four concrete subclasses of Parameter: Mandatory, Optional, Star, StarStar.
24 *
25 * <p>See FunctionSignature for how a valid list of Parameter's is organized as a signature, e.g.
26 * def foo(mandatory, optional = e1, *args, mandatorynamedonly, optionalnamedonly = e2, **kw): ...
27 *
28 * <p>V is the class of a defaultValue (Expression at compile-time, Object at runtime),
29 * T is the class of a type (Expression at compile-time, SkylarkType at runtime).
30 */
31public abstract class Parameter<V, T> extends Argument {
32
Taras Tsugrii36941362018-06-08 16:31:53 -070033 @Nullable protected final Identifier identifier;
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000034 @Nullable protected final T type;
35
Taras Tsugrii36941362018-06-08 16:31:53 -070036 private Parameter(@Nullable Identifier identifier, @Nullable T type) {
37 this.identifier = identifier;
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000038 this.type = type;
39 }
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000040
41 public boolean isMandatory() {
42 return false;
43 }
brandjone2ffd5d2017-06-27 18:14:54 +020044
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000045 public boolean isOptional() {
46 return false;
47 }
brandjone2ffd5d2017-06-27 18:14:54 +020048
Laurent Le Brune51a4d22016-10-11 18:04:16 +000049 @Override
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000050 public boolean isStar() {
51 return false;
52 }
brandjone2ffd5d2017-06-27 18:14:54 +020053
Laurent Le Brune51a4d22016-10-11 18:04:16 +000054 @Override
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000055 public boolean isStarStar() {
56 return false;
57 }
brandjone2ffd5d2017-06-27 18:14:54 +020058
59 @Nullable
60 public String getName() {
Taras Tsugrii36941362018-06-08 16:31:53 -070061 return identifier != null ? identifier.getName() : null;
62 }
63
64 @Nullable
65 public Identifier getIdentifier() {
66 return identifier;
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000067 }
brandjone2ffd5d2017-06-27 18:14:54 +020068
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000069 public boolean hasName() {
70 return true;
71 }
brandjone2ffd5d2017-06-27 18:14:54 +020072
73 @Nullable
74 public T getType() {
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000075 return type;
76 }
brandjone2ffd5d2017-06-27 18:14:54 +020077
78 @Nullable
79 public V getDefaultValue() {
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000080 return null;
81 }
82
83 /** mandatory parameter (positional or key-only depending on position): Ident */
brandjon296cd492017-05-15 16:17:16 +020084 public static final class Mandatory<V, T> extends Parameter<V, T> {
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000085
Googlere0c5e622019-08-09 15:10:14 -070086 Mandatory(Identifier identifier) {
Taras Tsugrii36941362018-06-08 16:31:53 -070087 this(identifier, null);
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000088 }
89
Googler173824c2019-08-15 14:03:25 -070090 Mandatory(Identifier identifier, @Nullable T type) {
Taras Tsugrii36941362018-06-08 16:31:53 -070091 super(identifier, type);
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000092 }
93
brandjone2ffd5d2017-06-27 18:14:54 +020094 @Override
95 public boolean isMandatory() {
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +000096 return true;
97 }
98
99 @Override
brandjone2ffd5d2017-06-27 18:14:54 +0200100 public void prettyPrint(Appendable buffer) throws IOException {
Taras Tsugrii36941362018-06-08 16:31:53 -0700101 buffer.append(getName());
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000102 }
103 }
104
105 /** optional parameter (positional or key-only depending on position): Ident = Value */
brandjon296cd492017-05-15 16:17:16 +0200106 public static final class Optional<V, T> extends Parameter<V, T> {
brandjone2ffd5d2017-06-27 18:14:54 +0200107
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000108 public final V defaultValue;
109
Googlere0c5e622019-08-09 15:10:14 -0700110 Optional(Identifier identifier, @Nullable V defaultValue) {
Taras Tsugrii36941362018-06-08 16:31:53 -0700111 this(identifier, null, defaultValue);
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000112 }
113
Googler173824c2019-08-15 14:03:25 -0700114 Optional(Identifier identifier, @Nullable T type, @Nullable V defaultValue) {
Taras Tsugrii36941362018-06-08 16:31:53 -0700115 super(identifier, type);
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000116 this.defaultValue = defaultValue;
117 }
118
brandjone2ffd5d2017-06-27 18:14:54 +0200119 @Override
120 @Nullable
121 public V getDefaultValue() {
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000122 return defaultValue;
123 }
124
brandjone2ffd5d2017-06-27 18:14:54 +0200125 @Override
126 public boolean isOptional() {
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000127 return true;
128 }
129
130 @Override
brandjone2ffd5d2017-06-27 18:14:54 +0200131 public void prettyPrint(Appendable buffer) throws IOException {
Taras Tsugrii36941362018-06-08 16:31:53 -0700132 buffer.append(getName());
brandjone2ffd5d2017-06-27 18:14:54 +0200133 buffer.append('=');
134 // This should only ever be used on a parameter representing static information, i.e. with V
135 // and T instantiated as Expression.
136 ((Expression) defaultValue).prettyPrint(buffer);
137 }
138
139 // Keep this as a separate method so that it can be used regardless of what V and T are
140 // parameterized with.
141 @Override
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000142 public String toString() {
Taras Tsugrii36941362018-06-08 16:31:53 -0700143 return getName() + "=" + defaultValue;
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000144 }
145 }
146
147 /** extra positionals parameter (star): *identifier */
brandjon296cd492017-05-15 16:17:16 +0200148 public static final class Star<V, T> extends Parameter<V, T> {
brandjone2ffd5d2017-06-27 18:14:54 +0200149
Googlere0c5e622019-08-09 15:10:14 -0700150 Star(@Nullable Identifier identifier, @Nullable T type) {
Taras Tsugrii36941362018-06-08 16:31:53 -0700151 super(identifier, type);
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000152 }
153
Googlere0c5e622019-08-09 15:10:14 -0700154 Star(@Nullable Identifier identifier) {
Taras Tsugrii36941362018-06-08 16:31:53 -0700155 this(identifier, null);
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000156 }
157
158 @Override
159 public boolean hasName() {
Taras Tsugrii36941362018-06-08 16:31:53 -0700160 return getName() != null;
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000161 }
162
brandjone2ffd5d2017-06-27 18:14:54 +0200163 @Override
164 public boolean isStar() {
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000165 return true;
166 }
167
brandjone2ffd5d2017-06-27 18:14:54 +0200168 @Override
169 public void prettyPrint(Appendable buffer) throws IOException {
170 buffer.append('*');
Taras Tsugrii36941362018-06-08 16:31:53 -0700171 if (getName() != null) {
172 buffer.append(getName());
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000173 }
174 }
175 }
176
177 /** extra keywords parameter (star_star): **identifier */
brandjon296cd492017-05-15 16:17:16 +0200178 public static final class StarStar<V, T> extends Parameter<V, T> {
brandjone2ffd5d2017-06-27 18:14:54 +0200179
Googlere0c5e622019-08-09 15:10:14 -0700180 StarStar(Identifier identifier, @Nullable T type) {
Taras Tsugrii36941362018-06-08 16:31:53 -0700181 super(identifier, type);
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000182 }
183
Googlere0c5e622019-08-09 15:10:14 -0700184 StarStar(Identifier identifier) {
Taras Tsugrii36941362018-06-08 16:31:53 -0700185 this(identifier, null);
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000186 }
187
brandjone2ffd5d2017-06-27 18:14:54 +0200188 @Override
189 public boolean isStarStar() {
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000190 return true;
191 }
192
193 @Override
brandjone2ffd5d2017-06-27 18:14:54 +0200194 public void prettyPrint(Appendable buffer) throws IOException {
195 buffer.append("**");
Taras Tsugrii36941362018-06-08 16:31:53 -0700196 buffer.append(getName());
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000197 }
198 }
199
200 @Override
Taras Tsugrii36941362018-06-08 16:31:53 -0700201 @SuppressWarnings("unchecked")
Googler4ace4652019-09-16 07:47:08 -0700202 public void accept(NodeVisitor visitor) {
laurentlb04b4c662017-08-07 20:03:40 +0200203 visitor.visit((Parameter<Expression, Expression>) this);
Francois-Rene Rideau5dcdbf92015-02-19 18:36:17 +0000204 }
205}