From d1d9c3800ab56b3c825f72e3e997b0521cfac9ce Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 10 Jun 2023 11:36:34 +0100 Subject: Check named arg is not passed twice --- .../org/shedlang/compiler/typechecker/TypeChecker.java | 16 ++++++++++++---- .../errors/CannotPassNamedArgTwiceError.java | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/typechecker/errors/CannotPassNamedArgTwiceError.java (limited to 'src/main/java') 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(); 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; + } +} -- cgit v1.2.3