Parser: fix the location of ArgumentException

We now show the location of the exact argument, instead of pointing at the end of the function call.

RELNOTES: None.
PiperOrigin-RevId: 220320701
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Argument.java b/src/main/java/com/google/devtools/build/lib/syntax/Argument.java
index 09f5120..970e28f 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Argument.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Argument.java
@@ -14,6 +14,7 @@
 package com.google.devtools.build.lib.syntax;
 
 import com.google.common.base.Preconditions;
+import com.google.devtools.build.lib.events.Location;
 import java.io.IOException;
 import java.util.List;
 import javax.annotation.Nullable;
@@ -170,10 +171,17 @@
   }
 
   /** Some arguments failed to satisfy python call convention strictures */
-  protected static class ArgumentException extends Exception {
+  static class ArgumentException extends Exception {
+    Location location;
+
     /** construct an ArgumentException from a message only */
-    public ArgumentException(String message) {
+    ArgumentException(Location location, String message) {
       super(message);
+      this.location = location;
+    }
+
+    Location getLocation() {
+      return location;
     }
   }
 
@@ -189,19 +197,20 @@
     boolean hasKwArg = false;
     for (Passed arg : arguments) {
       if (hasKwArg) {
-        throw new ArgumentException("argument after **kwargs");
+        throw new ArgumentException(arg.getLocation(), "argument after **kwargs");
       }
       if (arg.isPositional()) {
         if (hasNamed) {
-          throw new ArgumentException("non-keyword arg after keyword arg");
+          throw new ArgumentException(arg.getLocation(), "non-keyword arg after keyword arg");
         } else if (arg.isStar()) {
-          throw new ArgumentException("only named arguments may follow *expression");
+          throw new ArgumentException(
+              arg.getLocation(), "only named arguments may follow *expression");
         }
       } else if (arg.isKeyword()) {
         hasNamed = true;
       } else if (arg.isStar()) {
         if (hasStar) {
-          throw new ArgumentException("more than one *stararg");
+          throw new ArgumentException(arg.getLocation(), "more than one *stararg");
         }
         hasStar = true;
       } else {
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
index 3e9ebd5..dd79d66 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
@@ -539,7 +539,7 @@
     try {
       Argument.validateFuncallArguments(arguments);
     } catch (Argument.ArgumentException e) {
-      reportError(lexer.createLocation(token.left, token.right), e.getMessage());
+      reportError(e.getLocation(), e.getMessage());
     }
     return arguments;
   }