Implement ctx.actions.do_nothing instead of ctx.empty_action

RELNOTES: None.
PiperOrigin-RevId: 160621674
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java
index ecfff67..2bd1b4e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java
@@ -13,10 +13,17 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules;
 
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.actions.Action;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.extra.SpawnInfo;
+import com.google.devtools.build.lib.analysis.PseudoAction;
 import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.skylarkinterface.Param;
+import com.google.devtools.build.lib.skylarkinterface.ParamType;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
@@ -24,7 +31,11 @@
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.Printer;
 import com.google.devtools.build.lib.syntax.Runtime;
+import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
 import com.google.devtools.build.lib.vfs.PathFragment;
+import java.nio.charset.StandardCharsets;
+import java.util.UUID;
 
 /**
  * Provides a Skylark interface for all action creation needs.
@@ -132,7 +143,57 @@
   }
 
 
-    @Override
+  @SkylarkCallable(
+      name = "do_nothing",
+      doc =
+          "Creates an empty action that neither executes a command nor produces any "
+              + "output, but that is useful for inserting 'extra actions'.",
+      parameters = {
+          @Param(
+              name = "mnemonic",
+              type = String.class,
+              named = true,
+              positional = false,
+              doc = "a one-word description of the action, e.g. CppCompile or GoLink."
+          ),
+          @Param(
+              name = "inputs",
+              allowedTypes = {
+                  @ParamType(type = SkylarkList.class),
+                  @ParamType(type = SkylarkNestedSet.class),
+              },
+              generic1 = Artifact.class,
+              named = true,
+              positional = false,
+              defaultValue = "[]",
+              doc = "list of the input files of the action."
+          ),
+      }
+  )
+  public void doNothing(String mnemonic, Object inputs) throws EvalException {
+    context.checkMutable("actions.do_nothing");
+    NestedSet<Artifact> inputSet = inputs instanceof SkylarkNestedSet
+        ? ((SkylarkNestedSet) inputs).getSet(Artifact.class)
+        : NestedSetBuilder.<Artifact>compileOrder()
+            .addAll(((SkylarkList) inputs).getContents(Artifact.class, "inputs"))
+            .build();
+    Action action =
+        new PseudoAction<>(
+            UUID.nameUUIDFromBytes(
+                String.format("empty action %s", ruleContext.getLabel())
+                    .getBytes(StandardCharsets.UTF_8)),
+            ruleContext.getActionOwner(),
+            inputSet,
+            ImmutableList.of(PseudoAction.getDummyOutput(ruleContext)),
+            mnemonic,
+            SpawnInfo.spawnInfo,
+            SpawnInfo.newBuilder().build());
+    ruleContext.registerAction(action);
+  }
+
+
+
+  @Override
   public boolean isImmutable() {
     return context.isImmutable();
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
index 5908834..9488165 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
@@ -16,17 +16,13 @@
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.lib.actions.Action;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.RunfilesSupplier;
-import com.google.devtools.build.lib.actions.extra.SpawnInfo;
 import com.google.devtools.build.lib.analysis.AbstractConfiguredTarget;
 import com.google.devtools.build.lib.analysis.CommandHelper;
 import com.google.devtools.build.lib.analysis.FileProvider;
 import com.google.devtools.build.lib.analysis.FilesToRunProvider;
 import com.google.devtools.build.lib.analysis.LocationExpander;
-import com.google.devtools.build.lib.analysis.PseudoAction;
-import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.analysis.Runfiles;
 import com.google.devtools.build.lib.analysis.RunfilesProvider;
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
@@ -35,8 +31,6 @@
 import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
 import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
 import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.skylarkinterface.Param;
 import com.google.devtools.build.lib.skylarkinterface.ParamType;
@@ -62,7 +56,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.UUID;
 
 // TODO(bazel-team): function argument names are often duplicated,
 // figure out a nicely readable way to get rid of the duplications.
@@ -444,7 +437,9 @@
   @SkylarkSignature(
     name = "empty_action",
     doc =
-        "Creates an empty action that neither executes a command nor produces any "
+        "DEPRECATED. Use <a href=\"actions.html#do_nothing\">ctx.actions.do_nothing</a> instead."
+            + " <br>"
+            + "Creates an empty action that neither executes a command nor produces any "
             + "output, but that is useful for inserting 'extra actions'.",
     objectType = SkylarkRuleContext.class,
     returnType = Runtime.NoneType.class,
@@ -475,45 +470,11 @@
       new BuiltinFunction("empty_action") {
         @SuppressWarnings("unused")
         public Runtime.NoneType invoke(SkylarkRuleContext ctx, String mnemonic, Object inputs)
-            throws EvalException, ConversionException {
+            throws EvalException {
           ctx.checkMutable("empty_action");
-          RuleContext ruleContext = ctx.getRuleContext();
-          NestedSet<Artifact> inputSet = inputs instanceof SkylarkNestedSet
-              ? ((SkylarkNestedSet) inputs).getSet(Artifact.class)
-              : convertInputs((SkylarkList) inputs);
-          Action action =
-              new PseudoAction<>(
-                  generateUuid(ruleContext),
-                  ruleContext.getActionOwner(),
-                  inputSet,
-                  generateDummyOutputs(ruleContext),
-                  mnemonic,
-                  SpawnInfo.spawnInfo,
-                  createEmptySpawnInfo());
-          ruleContext.registerAction(action);
-
+          ctx.actions().doNothing(mnemonic, inputs);
           return Runtime.NONE;
         }
-
-        private NestedSet<Artifact> convertInputs(SkylarkList inputs) throws EvalException {
-          return NestedSetBuilder.<Artifact>compileOrder()
-              .addAll(inputs.getContents(Artifact.class, "inputs"))
-              .build();
-        }
-
-        protected UUID generateUuid(RuleContext ruleContext) {
-          return UUID.nameUUIDFromBytes(
-              String.format("empty action %s", ruleContext.getLabel())
-                  .getBytes(StandardCharsets.UTF_8));
-        }
-
-        protected ImmutableList<Artifact> generateDummyOutputs(RuleContext ruleContext) {
-          return ImmutableList.of(PseudoAction.getDummyOutput(ruleContext));
-        }
-
-        protected SpawnInfo createEmptySpawnInfo() {
-          return SpawnInfo.newBuilder().build();
-        }
       };
 
   @SkylarkSignature(
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
index 5ea7fd8..a2bac61 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
@@ -582,7 +582,7 @@
     scratch.file(
         "x/extension.bzl",
         "def _aspect_impl(target, ctx):",
-        "  ctx.empty_action(mnemonic='Mnemonic')",
+        "  ctx.actions.do_nothing(mnemonic='Mnemonic')",
         "  return struct()",
         "aspect1 = aspect(_aspect_impl, attr_aspects=['deps'])",
         "aspect2 = aspect(_aspect_impl, attr_aspects=['extra_deps'])",
@@ -647,7 +647,7 @@
     scratch.file(
         "x/extension.bzl",
         "def _aspect_impl(target, ctx):",
-        "  ctx.empty_action(mnemonic='Mnemonic')",
+        "  ctx.actions.do_nothing(mnemonic='Mnemonic')",
         "  return struct()",
         "aspect1 = aspect(_aspect_impl, attr_aspects=['deps'], attrs =",
         "    {'param': attr.string(values = ['a', 'b'])})",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java b/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
index cd2c949..1100ce4 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
@@ -1294,7 +1294,7 @@
     scratch.file(
         "x/extension.bzl",
         "def _aspect1_impl(target, ctx):",
-        "  ctx.empty_action(mnemonic='Mnemonic')",
+        "  ctx.actions.do_nothing(mnemonic='Mnemonic')",
         "  return struct()",
         "aspect1 = aspect(_aspect1_impl, attr_aspects=['deps'])",
         "",
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
index 3333e6b..202bc66 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
@@ -1861,6 +1861,7 @@
       "actions.declare_file('foo.txt', sibling = file)",
       "actions.declare_directory('foo.txt')",
       "actions.declare_directory('foo.txt', sibling = file)",
+      "actions.do_nothing(mnemonic = 'foo', inputs = [file])",
       "check_placeholders('foo', [])",
       "action(command = 'foo', outputs = [file])",
       "file_action(file, 'foo')",
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
index 21f6e08..9677078 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
@@ -433,14 +433,14 @@
 
     checkErrorContains(
         ruleContext,
-        "missing mandatory named-only argument 'mnemonic' while calling empty_action",
-        "ruleContext.empty_action(inputs = ruleContext.files.srcs)");
+        "parameter 'mnemonic' has no default value, in method do_nothing(list inputs) of 'actions'",
+        "ruleContext.actions.do_nothing(inputs = ruleContext.files.srcs)");
   }
 
   private void checkEmptyAction(SkylarkRuleContext ruleContext, String namedArgs) throws Exception {
     assertThat(
             evalRuleContextCode(
-                ruleContext, String.format("ruleContext.empty_action(%s)", namedArgs)))
+                ruleContext, String.format("ruleContext.actions.do_nothing(%s)", namedArgs)))
         .isEqualTo(Runtime.NONE);
   }
 
@@ -449,7 +449,7 @@
     scratch.file(
         "test/empty.bzl",
         "def _impl(ctx):",
-        "  ctx.empty_action(",
+        "  ctx.actions.do_nothing(",
         "      inputs = ctx.files.srcs,",
         "      mnemonic = 'EA',",
         "  )",