vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 1 | // Copyright 2017 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 | package com.google.devtools.build.lib.analysis; |
| 15 | |
vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 16 | import com.google.devtools.build.lib.actions.Artifact; |
adonovan | bc74d1d | 2020-04-30 12:08:31 -0700 | [diff] [blame] | 17 | import com.google.devtools.build.lib.collect.nestedset.Depset; |
vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 18 | import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 19 | import com.google.devtools.build.lib.packages.BuiltinProvider; |
dslomov | f129657 | 2017-08-22 16:29:06 +0200 | [diff] [blame] | 20 | import com.google.devtools.build.lib.packages.NativeInfo; |
gregce | 59f5cba | 2020-07-22 12:18:43 -0700 | [diff] [blame] | 21 | import com.google.devtools.build.lib.starlarkbuildapi.DefaultInfoApi; |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 22 | import javax.annotation.Nullable; |
adonovan | 450c7ad | 2020-09-14 13:00:21 -0700 | [diff] [blame] | 23 | import net.starlark.java.eval.EvalException; |
| 24 | import net.starlark.java.eval.Starlark; |
| 25 | import net.starlark.java.eval.StarlarkThread; |
| 26 | import net.starlark.java.syntax.Location; |
vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 27 | |
dslomov | 375f95b | 2017-08-21 12:52:41 +0200 | [diff] [blame] | 28 | /** DefaultInfo is provided by all targets implicitly and contains all standard fields. */ |
vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 29 | @Immutable |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 30 | public final class DefaultInfo extends NativeInfo implements DefaultInfoApi { |
vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 31 | |
Googler | d21a0d1 | 2019-11-21 13:52:30 -0800 | [diff] [blame] | 32 | private final Depset files; |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 33 | private final Runfiles runfiles; |
| 34 | private final Runfiles dataRunfiles; |
| 35 | private final Runfiles defaultRunfiles; |
| 36 | private final Artifact executable; |
vladmos | aa5e060 | 2017-04-12 17:43:53 +0000 | [diff] [blame] | 37 | private final FilesToRunProvider filesToRunProvider; |
vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 38 | |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 39 | /** |
| 40 | * Singleton instance of the provider type for {@link DefaultInfo}. |
| 41 | */ |
| 42 | public static final DefaultInfoProvider PROVIDER = new DefaultInfoProvider(); |
dslomov | 3aa7d2f | 2017-04-11 17:55:55 +0000 | [diff] [blame] | 43 | |
dslomov | 375f95b | 2017-08-21 12:52:41 +0200 | [diff] [blame] | 44 | private DefaultInfo( |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 45 | @Nullable RunfilesProvider runfilesProvider, |
vladmos | aa5e060 | 2017-04-12 17:43:53 +0000 | [diff] [blame] | 46 | FileProvider fileProvider, |
| 47 | FilesToRunProvider filesToRunProvider) { |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 48 | this( |
| 49 | Location.BUILTIN, |
Googler | 1a6a5a1 | 2019-11-22 11:54:01 -0800 | [diff] [blame] | 50 | Depset.of(Artifact.TYPE, fileProvider.getFilesToBuild()), |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 51 | Runfiles.EMPTY, |
| 52 | (runfilesProvider == null) ? Runfiles.EMPTY : runfilesProvider.getDataRunfiles(), |
| 53 | (runfilesProvider == null) ? Runfiles.EMPTY : runfilesProvider.getDefaultRunfiles(), |
| 54 | filesToRunProvider.getExecutable(), |
Googler | d21a0d1 | 2019-11-21 13:52:30 -0800 | [diff] [blame] | 55 | filesToRunProvider); |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 56 | } |
| 57 | |
| 58 | private DefaultInfo( |
| 59 | Location loc, |
Googler | d21a0d1 | 2019-11-21 13:52:30 -0800 | [diff] [blame] | 60 | Depset files, |
| 61 | Runfiles runfiles, |
| 62 | Runfiles dataRunfiles, |
| 63 | Runfiles defaultRunfiles, |
| 64 | Artifact executable, |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 65 | @Nullable FilesToRunProvider filesToRunProvider) { |
| 66 | super(PROVIDER, loc); |
| 67 | this.files = files; |
| 68 | this.runfiles = runfiles; |
| 69 | this.dataRunfiles = dataRunfiles; |
| 70 | this.defaultRunfiles = defaultRunfiles; |
| 71 | this.executable = executable; |
vladmos | aa5e060 | 2017-04-12 17:43:53 +0000 | [diff] [blame] | 72 | this.filesToRunProvider = filesToRunProvider; |
vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 73 | } |
| 74 | |
dslomov | 375f95b | 2017-08-21 12:52:41 +0200 | [diff] [blame] | 75 | public static DefaultInfo build( |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 76 | @Nullable RunfilesProvider runfilesProvider, |
vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 77 | FileProvider fileProvider, |
| 78 | FilesToRunProvider filesToRunProvider) { |
dslomov | f129657 | 2017-08-22 16:29:06 +0200 | [diff] [blame] | 79 | return new DefaultInfo(runfilesProvider, fileProvider, filesToRunProvider); |
vladmos | aa5e060 | 2017-04-12 17:43:53 +0000 | [diff] [blame] | 80 | } |
| 81 | |
| 82 | @Override |
Googler | d21a0d1 | 2019-11-21 13:52:30 -0800 | [diff] [blame] | 83 | public Depset getFiles() { |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 84 | return files; |
vladmos | aa5e060 | 2017-04-12 17:43:53 +0000 | [diff] [blame] | 85 | } |
vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 86 | |
vladmos | aa5e060 | 2017-04-12 17:43:53 +0000 | [diff] [blame] | 87 | @Override |
Googler | 3e1bf5c | 2019-11-04 12:41:49 -0800 | [diff] [blame] | 88 | public FilesToRunProvider getFilesToRun() { |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 89 | return filesToRunProvider; |
| 90 | } |
| 91 | |
| 92 | /** |
| 93 | * Returns a set of runfiles acting as both the data runfiles and the default runfiles. |
| 94 | * |
| 95 | * This is kept for legacy reasons. |
| 96 | */ |
| 97 | public Runfiles getStatelessRunfiles() { |
| 98 | return runfiles; |
| 99 | } |
| 100 | |
| 101 | @Override |
| 102 | public Runfiles getDataRunfiles() { |
| 103 | return dataRunfiles; |
| 104 | } |
| 105 | |
| 106 | @Override |
| 107 | public Runfiles getDefaultRunfiles() { |
cparsons | fba7cfb | 2018-06-26 14:15:18 -0700 | [diff] [blame] | 108 | if (dataRunfiles == null && defaultRunfiles == null) { |
gregce | ca48e9a | 2020-04-14 08:54:38 -0700 | [diff] [blame] | 109 | // This supports the legacy Starlark runfiles constructor -- if the 'runfiles' attribute |
cparsons | fba7cfb | 2018-06-26 14:15:18 -0700 | [diff] [blame] | 110 | // is used, then default_runfiles will return all runfiles. |
| 111 | return runfiles; |
| 112 | } else { |
| 113 | return defaultRunfiles; |
| 114 | } |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 115 | } |
| 116 | |
| 117 | /** |
| 118 | * If the rule producing this info object is marked 'executable' or 'test', this is an artifact |
| 119 | * representing the file that should be executed to run the target. This is null otherwise. |
| 120 | */ |
| 121 | public Artifact getExecutable() { |
| 122 | return executable; |
| 123 | } |
| 124 | |
| 125 | /** |
| 126 | * Provider implementation for {@link DefaultInfoApi}. |
| 127 | */ |
| 128 | public static class DefaultInfoProvider extends BuiltinProvider<DefaultInfo> |
| 129 | implements DefaultInfoApi.DefaultInfoApiProvider<Runfiles, Artifact> { |
| 130 | private DefaultInfoProvider() { |
| 131 | super("DefaultInfo", DefaultInfo.class); |
| 132 | } |
| 133 | |
| 134 | @Override |
adonovan | 7891d3b | 2020-01-22 12:40:50 -0800 | [diff] [blame] | 135 | public DefaultInfo constructor( |
| 136 | Object files, |
| 137 | Object runfilesObj, |
| 138 | Object dataRunfilesObj, |
| 139 | Object defaultRunfilesObj, |
| 140 | Object executable, |
| 141 | StarlarkThread thread) |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 142 | throws EvalException { |
| 143 | |
| 144 | Runfiles statelessRunfiles = castNoneToNull(Runfiles.class, runfilesObj); |
| 145 | Runfiles dataRunfiles = castNoneToNull(Runfiles.class, dataRunfilesObj); |
| 146 | Runfiles defaultRunfiles = castNoneToNull(Runfiles.class, defaultRunfilesObj); |
| 147 | |
| 148 | if ((statelessRunfiles != null) && (dataRunfiles != null || defaultRunfiles != null)) { |
adonovan | 7891d3b | 2020-01-22 12:40:50 -0800 | [diff] [blame] | 149 | throw Starlark.errorf( |
| 150 | "Cannot specify the provider 'runfiles' together with 'data_runfiles' or" |
| 151 | + " 'default_runfiles'"); |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 152 | } |
| 153 | |
| 154 | return new DefaultInfo( |
adonovan | 7891d3b | 2020-01-22 12:40:50 -0800 | [diff] [blame] | 155 | thread.getCallerLocation(), |
Googler | d21a0d1 | 2019-11-21 13:52:30 -0800 | [diff] [blame] | 156 | castNoneToNull(Depset.class, files), |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 157 | statelessRunfiles, |
| 158 | dataRunfiles, |
| 159 | defaultRunfiles, |
Googler | d21a0d1 | 2019-11-21 13:52:30 -0800 | [diff] [blame] | 160 | castNoneToNull(Artifact.class, executable), |
| 161 | null); |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 162 | } |
| 163 | } |
| 164 | |
| 165 | private static <T> T castNoneToNull(Class<T> clazz, Object value) { |
Googler | 641bdf7 | 2019-11-12 10:32:26 -0800 | [diff] [blame] | 166 | if (value == Starlark.NONE) { |
cparsons | dcd0abc | 2018-06-21 10:13:53 -0700 | [diff] [blame] | 167 | return null; |
| 168 | } else { |
| 169 | return clazz.cast(value); |
| 170 | } |
vladmos | 360fb4d | 2017-04-11 11:14:22 +0000 | [diff] [blame] | 171 | } |
| 172 | } |