From 6b2577d3b4844b06fc054d56559a1b0d51e48e84 Mon Sep 17 00:00:00 2001 From: gnembon Date: Wed, 23 Jun 2021 04:21:50 -0300 Subject: [PATCH 1/3] scarpet app command system will warn on repeated arguments. Fixes #935 --- src/main/java/carpet/script/command/CommandToken.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/carpet/script/command/CommandToken.java b/src/main/java/carpet/script/command/CommandToken.java index 07953b72..3949e39b 100644 --- a/src/main/java/carpet/script/command/CommandToken.java +++ b/src/main/java/carpet/script/command/CommandToken.java @@ -9,6 +9,7 @@ import net.minecraft.server.command.ServerCommandSource; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -46,10 +47,17 @@ public class CommandToken implements Comparable spec = spec.trim(); if (spec.isEmpty()) return Collections.emptyList(); List elements = new ArrayList<>(); + HashSet seenArgs = new HashSet<>(); for (String el: spec.split("\\s+")) { CommandToken tok = CommandToken.getToken(el, host); if (tok == null) throw CommandArgument.error("Unrecognized command token: "+ el); + if (tok.isArgument) + { + if (seenArgs.contains(tok.surface)) + throw CommandArgument.error("Repeated command argument: "+tok.surface+", for '"+spec+"'. Argument names have to be unique"); + seenArgs.add(tok.surface); + } elements.add(tok); } return elements; From 979032688ddbde6e697f430b9e8c304599a50f7a Mon Sep 17 00:00:00 2001 From: gnembon Date: Wed, 23 Jun 2021 04:26:13 -0300 Subject: [PATCH 2/3] docs --- docs/scarpet/api/Overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/scarpet/api/Overview.md b/docs/scarpet/api/Overview.md index ff24c98a..efdb6b6b 100644 --- a/docs/scarpet/api/Overview.md +++ b/docs/scarpet/api/Overview.md @@ -240,7 +240,7 @@ paths with functions to execute, and optionally, custom argument types. Commands the key (can be empty) consists of the execution path with the command syntax, which consists of literals (as is) and arguments (wrapped with `<>`), with the name / suffix of the name of the attribute indicating its type, and the value represent function to call, either function values, -defined function names, or functions with some default arguments. Values extracted from commands will be passed to the +defined function names, or functions with some default arguments. Argument names need to be unique for each command. Values extracted from commands will be passed to the functions and executed. By default, command list will be checked for ambiguities (commands with the same path up to some point that further use different attributes), causing app loading error if that happens, however this can be suppressed by specifying `'allow_command_conflicts'`. From 85d60b283f6f69504eb5a87addb72dc9a0bed490 Mon Sep 17 00:00:00 2001 From: gnembon Date: Wed, 23 Jun 2021 13:36:14 -0300 Subject: [PATCH 3/3] more flexible dealing with custom argument types, allowing _ in custom types. Fixes #936 --- docs/scarpet/api/Overview.md | 12 +++++++++--- .../carpet/script/command/CommandArgument.java | 14 ++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/docs/scarpet/api/Overview.md b/docs/scarpet/api/Overview.md index efdb6b6b..e4979462 100644 --- a/docs/scarpet/api/Overview.md +++ b/docs/scarpet/api/Overview.md @@ -188,7 +188,7 @@ baz(entities) -> // same thing ``` It works similarly to the auto command, but arguments get their inferred types based on the argument -names, looking at the full name, or the suffix after the last `_` that indicates the variable type. For instance, variable named `float` will +names, looking at the full name, or any suffix when splitting on `_` that indicates the variable type. For instance, variable named `float` will be parsed as a floating point number, but it can be named `'first_float'` or `'other_float'` as well. Any variable that is not supported, will be parsed as a `'string'` type. @@ -253,8 +253,14 @@ and less frequently used features, like forks and redirects, used pretty much on ### Command argument types -There are several default argument types that can be used directly without specifying custom types. Each argument can be -customized in the `'arguments'` section of the app config, specifying its base type, via `'type'` that needs +Argument types differ from actual argument names that the types are the suffixes of the used argument names, when separated with +`'_'` symbol. For example argument name `'from_pos'` will be interpreted as a built-in type `'int'` and provided to the command system +as a name `'from_pos'`, however if you define a custom type `'from_pos'`, your custom type will be used instead. +Longer suffixes take priority over shorter prefixes, then user defined suffixes mask build-in prefixes. + +There are several default argument types that can be used directly without specifying custom types. + +Each argument can be customized in the `'arguments'` section of the app config, specifying its base type, via `'type'` that needs to match any of the built-in types, with a series of optional modifiers. Shared modifiers include: * `suggest` - static list of suggestions to show above the command while typing * `suggester` - function taking one map argument, indicating current state of attributes in the parsed command diff --git a/src/main/java/carpet/script/command/CommandArgument.java b/src/main/java/carpet/script/command/CommandArgument.java index 1bb705b7..1a406c3c 100644 --- a/src/main/java/carpet/script/command/CommandArgument.java +++ b/src/main/java/carpet/script/command/CommandArgument.java @@ -269,10 +269,16 @@ public abstract class CommandArgument public static CommandArgument getTypeForArgument(String argument, CarpetScriptHost host) { String[] components = argument.split("_"); - String suffix = components[components.length-1]; - CommandArgument arg = host.appArgTypes.get(suffix); - if (arg != null) return arg; - return builtIns.getOrDefault(suffix, DEFAULT); + CommandArgument arg; + for (int i = 0; i < components.length; i++) + { + String candidate = String.join("_", Arrays.asList(components).subList(i, components.length)); + arg = host.appArgTypes.get(candidate); + if (arg != null) return arg; + arg = builtIns.get(candidate); + if (arg != null) return arg; + } + return DEFAULT; } public static RequiredArgumentBuilder argumentNode(String param, CarpetScriptHost host) throws CommandSyntaxException