cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 1 | // Copyright 2018 The Bazel Authors. All rights reserved. |
| 2 | // |
| 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 | |
| 15 | package com.google.devtools.build.skydoc.fakebuildapi; |
| 16 | |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 17 | import com.google.common.collect.ImmutableList; |
| 18 | import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi; |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 19 | import com.google.devtools.build.lib.skylarkbuildapi.SkylarkAttrApi; |
| 20 | import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 21 | import com.google.devtools.build.lib.skylarkinterface.StarlarkContext; |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 22 | import com.google.devtools.build.lib.syntax.Environment; |
| 23 | import com.google.devtools.build.lib.syntax.EvalException; |
| 24 | import com.google.devtools.build.lib.syntax.FuncallExpression; |
| 25 | import com.google.devtools.build.lib.syntax.SkylarkDict; |
| 26 | import com.google.devtools.build.lib.syntax.SkylarkList; |
cparsons | 5ece650 | 2019-04-17 10:19:41 -0700 | [diff] [blame] | 27 | import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeType; |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 28 | import java.util.ArrayList; |
| 29 | import java.util.List; |
| 30 | import java.util.Map; |
| 31 | import java.util.Map.Entry; |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 32 | |
| 33 | /** |
| 34 | * Fake implementation of {@link SkylarkAttrApi}. |
| 35 | */ |
| 36 | public class FakeSkylarkAttrApi implements SkylarkAttrApi { |
| 37 | |
| 38 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 39 | public Descriptor intAttribute( |
| 40 | Integer defaultInt, |
| 41 | String doc, |
| 42 | Boolean mandatory, |
| 43 | SkylarkList<?> values, |
| 44 | FuncallExpression ast, |
| 45 | Environment env, |
| 46 | StarlarkContext context) |
| 47 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 48 | return new FakeDescriptor(AttributeType.INT, doc, mandatory, ImmutableList.of()); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 49 | } |
| 50 | |
| 51 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 52 | public Descriptor stringAttribute( |
| 53 | String defaultString, |
| 54 | String doc, |
| 55 | Boolean mandatory, |
| 56 | SkylarkList<?> values, |
| 57 | FuncallExpression ast, |
| 58 | Environment env, |
| 59 | StarlarkContext context) |
| 60 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 61 | return new FakeDescriptor(AttributeType.STRING, doc, mandatory, ImmutableList.of()); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 62 | } |
| 63 | |
| 64 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 65 | public Descriptor labelAttribute( |
| 66 | Object defaultO, |
| 67 | String doc, |
| 68 | Boolean executable, |
| 69 | Object allowFiles, |
| 70 | Object allowSingleFile, |
| 71 | Boolean mandatory, |
| 72 | SkylarkList<?> providers, |
| 73 | Object allowRules, |
| 74 | Boolean singleFile, |
| 75 | Object cfg, |
| 76 | SkylarkList<?> aspects, |
| 77 | FuncallExpression ast, |
| 78 | Environment env, |
| 79 | StarlarkContext context) |
| 80 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 81 | List<List<String>> allNameGroups = new ArrayList<>(); |
| 82 | if (providers != null) { |
| 83 | allNameGroups = allProviderNameGroups(providers, env); |
| 84 | } |
| 85 | return new FakeDescriptor(AttributeType.LABEL, doc, mandatory, allNameGroups); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 89 | public Descriptor stringListAttribute( |
| 90 | Boolean mandatory, |
| 91 | Boolean nonEmpty, |
| 92 | Boolean allowEmpty, |
| 93 | SkylarkList<?> defaultList, |
| 94 | String doc, |
| 95 | FuncallExpression ast, |
| 96 | Environment env, |
| 97 | StarlarkContext context) |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 98 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 99 | return new FakeDescriptor(AttributeType.STRING_LIST, doc, mandatory, ImmutableList.of()); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 103 | public Descriptor intListAttribute( |
| 104 | Boolean mandatory, |
| 105 | Boolean nonEmpty, |
| 106 | Boolean allowEmpty, |
| 107 | SkylarkList<?> defaultList, |
| 108 | String doc, |
| 109 | FuncallExpression ast, |
| 110 | Environment env, |
| 111 | StarlarkContext context) |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 112 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 113 | return new FakeDescriptor(AttributeType.INT_LIST, doc, mandatory, ImmutableList.of()); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 114 | } |
| 115 | |
| 116 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 117 | public Descriptor labelListAttribute( |
| 118 | Boolean allowEmpty, |
| 119 | Object defaultList, |
| 120 | String doc, |
| 121 | Object allowFiles, |
| 122 | Object allowRules, |
| 123 | SkylarkList<?> providers, |
| 124 | SkylarkList<?> flags, |
| 125 | Boolean mandatory, |
| 126 | Boolean nonEmpty, |
| 127 | Object cfg, |
| 128 | SkylarkList<?> aspects, |
| 129 | FuncallExpression ast, |
| 130 | Environment env, |
| 131 | StarlarkContext context) |
| 132 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 133 | List<List<String>> allNameGroups = new ArrayList<>(); |
| 134 | if (providers != null) { |
| 135 | allNameGroups = allProviderNameGroups(providers, env); |
| 136 | } |
| 137 | return new FakeDescriptor(AttributeType.LABEL_LIST, doc, mandatory, allNameGroups); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 138 | } |
| 139 | |
| 140 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 141 | public Descriptor labelKeyedStringDictAttribute( |
| 142 | Boolean allowEmpty, |
| 143 | Object defaultList, |
| 144 | String doc, |
| 145 | Object allowFiles, |
| 146 | Object allowRules, |
| 147 | SkylarkList<?> providers, |
| 148 | SkylarkList<?> flags, |
| 149 | Boolean mandatory, |
| 150 | Boolean nonEmpty, |
| 151 | Object cfg, |
| 152 | SkylarkList<?> aspects, |
| 153 | FuncallExpression ast, |
| 154 | Environment env, |
| 155 | StarlarkContext context) |
| 156 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 157 | List<List<String>> allNameGroups = new ArrayList<>(); |
| 158 | if (providers != null) { |
| 159 | allNameGroups = allProviderNameGroups(providers, env); |
| 160 | } |
| 161 | return new FakeDescriptor(AttributeType.LABEL_STRING_DICT, doc, mandatory, allNameGroups); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 162 | } |
| 163 | |
| 164 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 165 | public Descriptor boolAttribute( |
| 166 | Boolean defaultO, |
| 167 | String doc, |
| 168 | Boolean mandatory, |
| 169 | FuncallExpression ast, |
| 170 | Environment env, |
| 171 | StarlarkContext context) |
| 172 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 173 | return new FakeDescriptor(AttributeType.BOOLEAN, doc, mandatory, ImmutableList.of()); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 177 | public Descriptor outputAttribute( |
| 178 | Object defaultO, |
| 179 | String doc, |
| 180 | Boolean mandatory, |
| 181 | FuncallExpression ast, |
| 182 | Environment env, |
| 183 | StarlarkContext context) |
| 184 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 185 | return new FakeDescriptor(AttributeType.OUTPUT, doc, mandatory, ImmutableList.of()); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 186 | } |
| 187 | |
| 188 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 189 | public Descriptor outputListAttribute( |
| 190 | Boolean allowEmpty, |
| 191 | Object defaultList, |
| 192 | String doc, |
| 193 | Boolean mandatory, |
| 194 | Boolean nonEmpty, |
| 195 | FuncallExpression ast, |
| 196 | Environment env, |
| 197 | StarlarkContext context) |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 198 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 199 | return new FakeDescriptor(AttributeType.OUTPUT_LIST, doc, mandatory, ImmutableList.of()); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 200 | } |
| 201 | |
| 202 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 203 | public Descriptor stringDictAttribute( |
| 204 | Boolean allowEmpty, |
| 205 | SkylarkDict<?, ?> defaultO, |
| 206 | String doc, |
| 207 | Boolean mandatory, |
| 208 | Boolean nonEmpty, |
| 209 | FuncallExpression ast, |
| 210 | Environment env, |
| 211 | StarlarkContext context) |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 212 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 213 | return new FakeDescriptor(AttributeType.STRING_DICT, doc, mandatory, ImmutableList.of()); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 214 | } |
| 215 | |
| 216 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 217 | public Descriptor stringListDictAttribute( |
| 218 | Boolean allowEmpty, |
| 219 | SkylarkDict<?, ?> defaultO, |
| 220 | String doc, |
| 221 | Boolean mandatory, |
| 222 | Boolean nonEmpty, |
| 223 | FuncallExpression ast, |
| 224 | Environment env, |
| 225 | StarlarkContext context) |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 226 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 227 | return new FakeDescriptor(AttributeType.STRING_LIST_DICT, doc, mandatory, ImmutableList.of()); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 228 | } |
| 229 | |
| 230 | @Override |
dannark | ec4f575 | 2019-01-10 13:07:01 -0800 | [diff] [blame] | 231 | public Descriptor licenseAttribute( |
| 232 | Object defaultO, |
| 233 | String doc, |
| 234 | Boolean mandatory, |
| 235 | FuncallExpression ast, |
| 236 | Environment env, |
| 237 | StarlarkContext context) |
| 238 | throws EvalException { |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 239 | return new FakeDescriptor(AttributeType.STRING_LIST, doc, mandatory, ImmutableList.of()); |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 240 | } |
| 241 | |
| 242 | @Override |
| 243 | public void repr(SkylarkPrinter printer) {} |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 244 | |
| 245 | /** |
| 246 | * Returns a list of provider name groups, given the value of a Starlark attribute's "providers" |
| 247 | * argument. |
| 248 | * |
| 249 | * <p>{@code providers} can either be a list of providers, or a list of lists of providers. If it |
| 250 | * is the first case, the entire list is considered a single group. In the second case, each of |
| 251 | * the inner lists is a group. |
| 252 | */ |
| 253 | private static List<List<String>> allProviderNameGroups(SkylarkList<?> providers, Environment env) |
| 254 | throws EvalException { |
| 255 | |
| 256 | List<List<String>> allNameGroups = new ArrayList<>(); |
| 257 | List<List<ProviderApi>> allProviderGroups = new ArrayList<>(); |
| 258 | for (Object object : providers) { |
| 259 | if (object instanceof ProviderApi) { |
| 260 | allProviderGroups.add(providers.getContents(ProviderApi.class, "providers")); |
| 261 | break; |
| 262 | } else if (object instanceof SkylarkList) { |
| 263 | allProviderGroups.add( |
| 264 | ((SkylarkList<?>) object).getContents(ProviderApi.class, "provider groups")); |
| 265 | } |
| 266 | } |
| 267 | |
| 268 | for (List<ProviderApi> providerGroup : allProviderGroups) { |
| 269 | List<String> nameGroup = providerNameGroup(providerGroup, env); |
| 270 | allNameGroups.add(nameGroup); |
| 271 | } |
| 272 | |
| 273 | return allNameGroups; |
| 274 | } |
| 275 | |
| 276 | /** Returns the names of the providers in the given group. */ |
| 277 | private static List<String> providerNameGroup(List<ProviderApi> providerGroup, Environment env) { |
| 278 | List<String> providerNameGroup = new ArrayList<>(); |
| 279 | for (ProviderApi provider : providerGroup) { |
| 280 | String providerName = providerName(provider, env); |
| 281 | providerNameGroup.add(providerName); |
| 282 | } |
| 283 | return providerNameGroup; |
| 284 | } |
| 285 | |
| 286 | /** |
| 287 | * Returns the name of {@code provider}. |
| 288 | * |
| 289 | * <p>{@code env} contains a {@code Map<String, Object>} where the values are built-in objects or |
| 290 | * objects defined in the file and the keys are the names of these objects. If a {@code provider} |
| 291 | * is in the map, the name of the provider is set as the key of this object in {@code bindings}. |
| 292 | * If it is not in the map, the provider may be part of a module in the map and the name will be |
| 293 | * set to "Unknown Provider". |
| 294 | */ |
| 295 | private static String providerName(ProviderApi provider, Environment env) { |
| 296 | Map<String, Object> bindings = env.getGlobals().getTransitiveBindings(); |
| 297 | if (bindings.containsValue(provider)) { |
| 298 | for (Entry<String, Object> envEntry : bindings.entrySet()) { |
| 299 | if (provider.equals(envEntry.getValue())) { |
| 300 | return envEntry.getKey(); |
| 301 | } |
| 302 | } |
| 303 | } |
| 304 | return "Unknown Provider"; |
| 305 | } |
cparsons | 5d85e75 | 2018-06-26 13:47:28 -0700 | [diff] [blame] | 306 | } |
kendalllane | 8584127 | 2019-08-07 15:01:07 -0700 | [diff] [blame^] | 307 | |