aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-10 11:36:34 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-10 11:36:34 +0100
commitd1d9c3800ab56b3c825f72e3e997b0521cfac9ce (patch)
treeb7b83c4d368320cf7016527322f5235cd17312ca /src/main/java
parentbf1707367f6c26ced547c3504f267a2c7ca275a4 (diff)
Check named arg is not passed twice
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java16
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/errors/CannotPassNamedArgTwiceError.java17
2 files changed, 29 insertions, 4 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index edfb961c..11f902b1 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -7,6 +7,8 @@ import org.shedlang.compiler.typechecker.typesets.TypeSets;
import org.shedlang.compiler.types.FunctionType;
import org.shedlang.compiler.types.Type;
+import java.util.HashSet;
+
public class TypeChecker {
private TypeChecker() {
}
@@ -57,6 +59,7 @@ public class TypeChecker {
checkExpressionType(typedArg, paramType, context);
}
+ var seenNamedArgNames = new HashSet<String>();
for (var typedArg : typedNamedArgs) {
var param = receiverType.namedParams().stream()
.filter(namedParam -> namedParam.name().equals(typedArg.name()))
@@ -64,13 +67,18 @@ public class TypeChecker {
.orElseThrow(() -> new UnexpectedNamedArgError(typedArg.name(), typedArg.source()));
checkExpressionType(typedArg.expression(), param.type(), context);
+
+ if (seenNamedArgNames.contains(typedArg.name())) {
+ throw new CannotPassNamedArgTwiceError(typedArg.name(), typedArg.source());
+ }
+
+ seenNamedArgNames.add(typedArg.name());
}
for (var namedParam : receiverType.namedParams()) {
- typedNamedArgs.stream()
- .filter(namedArg -> namedArg.name().equals(namedParam.name()))
- .findFirst()
- .orElseThrow(() -> new MissingNamedArgError(namedParam.name(), args.source()));
+ if (!seenNamedArgNames.contains(namedParam.name())) {
+ throw new MissingNamedArgError(namedParam.name(), args.source());
+ }
}
return new TypedArgsNode(typedPositionalArgs, typedNamedArgs, args.source());
diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/CannotPassNamedArgTwiceError.java b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotPassNamedArgTwiceError.java
new file mode 100644
index 00000000..168d46de
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotPassNamedArgTwiceError.java
@@ -0,0 +1,17 @@
+package org.shedlang.compiler.typechecker.errors;
+
+import org.shedlang.compiler.errors.SourceError;
+import org.shedlang.compiler.sources.Source;
+
+public class CannotPassNamedArgTwiceError extends SourceError {
+ private final String argName;
+
+ public CannotPassNamedArgTwiceError(String argName, Source source) {
+ super("Cannot pass named arg " + argName + " twice", source);
+ this.argName = argName;
+ }
+
+ public String argName() {
+ return argName;
+ }
+}