From 0df6725da8a0953c5643c5692c5244826e448d09 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Mon, 23 Dec 2024 15:40:36 +0000 Subject: Generate nicer errors for failures to parse main namespace name --- .../org/shedlang/compiler/config/BinConfig.java | 22 ++++++++++++++++---- .../shedlang/compiler/config/ExampleConfig.java | 7 ++++--- .../org/shedlang/compiler/config/GcConfig.java | 2 +- .../shedlang/compiler/config/ProfileConfig.java | 2 +- .../shedlang/compiler/config/toml/TomlString.java | 6 ++++++ .../compiler/config/toml/TomlTableWithSource.java | 24 ++++++++++++++++------ 6 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/config/toml/TomlString.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/config/BinConfig.java b/src/main/java/org/shedlang/compiler/config/BinConfig.java index f6f8918e..e91a6af4 100644 --- a/src/main/java/org/shedlang/compiler/config/BinConfig.java +++ b/src/main/java/org/shedlang/compiler/config/BinConfig.java @@ -1,18 +1,32 @@ package org.shedlang.compiler.config; +import org.shedlang.compiler.config.errors.ConfigError; import org.shedlang.compiler.config.toml.TomlTableWithSource; import org.shedlang.compiler.parser.SourceParser; import org.shedlang.compiler.sources.Sources; +import org.shedlang.compiler.tokeniser.UnexpectedTokenException; import org.shedlang.compiler.types.NamespaceName; +import java.text.MessageFormat; + public record BinConfig(String name, NamespaceName mainNamespace) { public static BinConfig fromToml(TomlTableWithSource table) { - var name = table.getString("name"); + var name = table.getString("name").value(); var mainNamespaceString = table.getString("main-namespace"); - // TODO: error checking - var mainNamespace = SourceParser.parseNamespaceName(Sources.string(mainNamespaceString)); - return new BinConfig(name, mainNamespace); + try { + var mainNamespace = SourceParser.parseNamespaceName(Sources.string(mainNamespaceString.value())); + return new BinConfig(name, mainNamespace); + } catch (UnexpectedTokenException exception) { + throw new ConfigError( + MessageFormat.format( + "Invalid namespace name.\n{0}\n\n{1}", + exception.getMessage(), + exception.source().describe() + ), + mainNamespaceString.source() + ); + } } } diff --git a/src/main/java/org/shedlang/compiler/config/ExampleConfig.java b/src/main/java/org/shedlang/compiler/config/ExampleConfig.java index f9f8dd35..abc311d3 100644 --- a/src/main/java/org/shedlang/compiler/config/ExampleConfig.java +++ b/src/main/java/org/shedlang/compiler/config/ExampleConfig.java @@ -1,5 +1,6 @@ package org.shedlang.compiler.config; +import org.shedlang.compiler.config.toml.TomlString; import org.shedlang.compiler.config.toml.TomlTableWithSource; import java.util.Optional; @@ -11,9 +12,9 @@ public record ExampleConfig( ) { public static ExampleConfig fromToml(TomlTableWithSource table) { return new ExampleConfig( - table.getString("bin"), - table.getStringOrNone("expected-output"), - table.getStringOrNone("expected-error") + table.getString("bin").value(), + table.getStringOrNone("expected-output").map(TomlString::value), + table.getStringOrNone("expected-error").map(TomlString::value) ); } } diff --git a/src/main/java/org/shedlang/compiler/config/GcConfig.java b/src/main/java/org/shedlang/compiler/config/GcConfig.java index 4192824a..fad51f63 100644 --- a/src/main/java/org/shedlang/compiler/config/GcConfig.java +++ b/src/main/java/org/shedlang/compiler/config/GcConfig.java @@ -9,7 +9,7 @@ public sealed interface GcConfig permits GcBumpConfig, GcMarkAndSweepConfig { GcConfig DEFAULT = GcMarkAndSweepConfig.DEFAULT; static GcConfig fromToml(TomlTableWithSource table) { - var name = table.getString("name"); + var name = table.getString("name").value(); return switch (name) { case "bump" -> diff --git a/src/main/java/org/shedlang/compiler/config/ProfileConfig.java b/src/main/java/org/shedlang/compiler/config/ProfileConfig.java index 3488b36b..cf8b4998 100644 --- a/src/main/java/org/shedlang/compiler/config/ProfileConfig.java +++ b/src/main/java/org/shedlang/compiler/config/ProfileConfig.java @@ -8,7 +8,7 @@ public record ProfileConfig(String name, Optional gc) { public static final ProfileConfig DEFAULT = new ProfileConfig("dev", Optional.empty()); public static ProfileConfig fromToml(TomlTableWithSource table) { - var name = table.getString("name"); + var name = table.getString("name").value(); var gc = table.getTable("gc").map(GcConfig::fromToml); return new ProfileConfig( diff --git a/src/main/java/org/shedlang/compiler/config/toml/TomlString.java b/src/main/java/org/shedlang/compiler/config/toml/TomlString.java new file mode 100644 index 00000000..b8aac9e5 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/config/toml/TomlString.java @@ -0,0 +1,6 @@ +package org.shedlang.compiler.config.toml; + +import org.shedlang.compiler.sources.Source; + +public record TomlString(String value, Source source) { +} diff --git a/src/main/java/org/shedlang/compiler/config/toml/TomlTableWithSource.java b/src/main/java/org/shedlang/compiler/config/toml/TomlTableWithSource.java index 8d0c1db9..f7ef240f 100644 --- a/src/main/java/org/shedlang/compiler/config/toml/TomlTableWithSource.java +++ b/src/main/java/org/shedlang/compiler/config/toml/TomlTableWithSource.java @@ -114,16 +114,20 @@ public class TomlTableWithSource { ); } - public Optional getStringOrNone(String key) { + public Optional getStringOrNone(String key) { var value = table.get(key); var valuePosition = table.inputPositionOf(key); - if (value == null) { + if (value == null || valuePosition == null) { return Optional.empty(); } if (value instanceof String valueString) { - return Optional.of(valueString); + var tomlString = new TomlString( + valueString, + TomlSource.sourceAtTomlPosition(fullSource, valuePosition) + ); + return Optional.of(tomlString); } throw new UnexpectedTypeConfigError( @@ -134,11 +138,11 @@ public class TomlTableWithSource { ); } - public String getString(String key) { + public TomlString getString(String key) { var value = table.get(key); var valuePosition = table.inputPositionOf(key); - if (value == null) { + if (value == null || valuePosition == null) { throw new ConfigError( MessageFormat.format("{0} is missing {1}", path, key), TomlSource.sourceAtTomlPosition(fullSource, position) @@ -146,7 +150,10 @@ public class TomlTableWithSource { } if (value instanceof String valueString) { - return valueString; + return new TomlString( + valueString, + TomlSource.sourceAtTomlPosition(fullSource, valuePosition) + ); } throw new UnexpectedTypeConfigError( @@ -199,4 +206,9 @@ public class TomlTableWithSource { TomlSource.sourceAtTomlPosition(fullSource, valuePosition) ); } + + public Optional getSource(String key) { + return Optional.ofNullable(table.inputPositionOf(key)) + .map(position -> TomlSource.sourceAtTomlPosition(fullSource, position)); + } } -- cgit v1.2.3