summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-08-29 19:45:38 +0100
committerMichael Williamson <mike@zwobble.org>2026-08-29 19:45:38 +0100
commit73b58b585b0e12b9baf263fdc55da2f2b501651f (patch)
tree89a5323be4808f8c74db4507aa03c655fabcc7ae /src
parent503786f64f2af7725b1b58408396000ede4b3cb4 (diff)
Generate empty TypeScript module for each namespace
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGenerator.java27
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGeneratorConfig.java2
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescripttypes/TypescriptTypesGenerator.java21
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptIdentifier.java32
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptModule.java28
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java27
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriterTests.java2
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptIdentifierMatcher.java41
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptModuleMatcher.java6
9 files changed, 166 insertions, 20 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGenerator.java
index ebc7166..f7745ff 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGenerator.java
@@ -1,9 +1,34 @@
package org.zwobble.hobgoblin.compiler.output.generators.typescript;
+import org.zwobble.hobgoblin.compiler.output.lang.typescript.TypescriptWriter;
+import org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier;
+import org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.stream.Collectors;
+
public class TypescriptGenerator {
+ private final Path outputPath;
private final TypescriptGeneratorConfig config;
- public TypescriptGenerator(TypescriptGeneratorConfig config) {
+ public TypescriptGenerator(Path outputPath, TypescriptGeneratorConfig config) {
+ this.outputPath = outputPath;
this.config = config;
}
+
+ public void write(TypescriptModule module) throws IOException {
+ var path = this.outputPath.resolve(
+ module.name().stream()
+ .map(name -> name.value())
+ .collect(Collectors.joining(File.separator)) + ".ts"
+ );
+
+ TypescriptWriter.writeTo(path, writer -> writer.writeModule(module));
+ }
+
+ public TypescriptIdentifier generateModuleName(String namespaceNamePart) {
+ return new TypescriptIdentifier(namespaceNamePart);
+ }
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGeneratorConfig.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGeneratorConfig.java
index 4026c14..6a93eea 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGeneratorConfig.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescript/TypescriptGeneratorConfig.java
@@ -4,7 +4,7 @@ import org.zwobble.json5.reader.Json5ObjectReader;
public record TypescriptGeneratorConfig() {
public static TypescriptGeneratorConfig parseLangsConfig(Json5ObjectReader langsJson) {
- var output = langsJson.getObject("typescript");
+ var output = langsJson.getObjectOrNone("typescript");
return new TypescriptGeneratorConfig();
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescripttypes/TypescriptTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescripttypes/TypescriptTypesGenerator.java
index 1d190a5..df308ab 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescripttypes/TypescriptTypesGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/typescripttypes/TypescriptTypesGenerator.java
@@ -6,6 +6,7 @@ import org.zwobble.hobgoblin.compiler.output.generators.Generator;
import org.zwobble.hobgoblin.compiler.output.generators.GeneratorDefinition;
import org.zwobble.hobgoblin.compiler.output.generators.typescript.TypescriptGenerator;
import org.zwobble.hobgoblin.compiler.output.generators.typescript.TypescriptGeneratorConfig;
+import org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule;
import org.zwobble.hobgoblin.compiler.typechecker.TypesInfo;
import org.zwobble.json5.reader.Json5ObjectReader;
@@ -47,22 +48,32 @@ public class TypescriptTypesGenerator implements Generator {
var typescriptConfig = TypescriptGeneratorConfig.parseLangsConfig(langsJson);
- var typescriptGenerator = new TypescriptGenerator(typescriptConfig);
+ var typescriptGenerator = new TypescriptGenerator(outputPath, typescriptConfig);
- return new TypescriptTypesGenerator(outputPath, typescriptGenerator);
+ return new TypescriptTypesGenerator(typescriptGenerator);
};
}
- private final Path outputPath;
private final TypescriptGenerator typescriptGenerator;
- private TypescriptTypesGenerator(Path outputPath, TypescriptGenerator typescriptGenerator) {
- this.outputPath = outputPath;
+ private TypescriptTypesGenerator(TypescriptGenerator typescriptGenerator) {
this.typescriptGenerator = typescriptGenerator;
}
@Override
public void generate(List<TypedNamespaceNode> namespaces, TypesInfo typesInfo) throws IOException {
+ for (var namespace : namespaces) {
+ var typescriptModule = generateNamespace(namespace);
+ this.typescriptGenerator.write(typescriptModule);
+ }
+ }
+
+ private TypescriptModule generateNamespace(TypedNamespaceNode namespace) {
+ var typescriptModuleName = namespace.namespaceName().parts().stream()
+ .map(part -> this.typescriptGenerator.generateModuleName(part))
+ .toList();
+
+ return new TypescriptModule(typescriptModuleName);
}
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptIdentifier.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptIdentifier.java
new file mode 100644
index 0000000..a87c792
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptIdentifier.java
@@ -0,0 +1,32 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.typescript.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier imports
+
+public record TypescriptIdentifier(
+ String value
+) {
+ public static org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier.Builder("");
+ }
+
+ public record Builder(
+ String value
+ ) {
+ public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier(value);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier.Builder withValue(String value) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier.Builder(value);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptModule.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptModule.java
index f66626b..cff3dd5 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptModule.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptModule.java
@@ -5,14 +5,34 @@ package org.zwobble.hobgoblin.compiler.output.lang.typescript.ast;
// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule imports
// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule imports
-public record TypescriptModule() {
+public record TypescriptModule(
+ java.util.List<org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier> name
+) {
public static org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.Builder arbitrary() {
- return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.Builder();
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.Builder(java.util.List.of());
}
- public record Builder() {
+ public record Builder(
+ java.util.List<org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier> name
+ ) {
public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule build() {
- return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule();
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule(name);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.Builder withName(java.util.List<org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier> name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.Builder(name);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.Builder addNameElement(org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier nameElement) {
+ var name = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier>(this.name);
+ name.add(nameElement);
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.Builder(name);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.Builder addNameElement(org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier.Builder nameElement) {
+ var name = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier>(this.name);
+ name.add(nameElement.build());
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.Builder(name);
}
// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.Builder body
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java
index 1c77a83..3cc7048 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java
@@ -32,6 +32,7 @@ public class ExampleTests {
var javaOutputPath = verifyJavaOutput(exampleSet);
var rustOutputPath = verifyRustOutput(exampleSet);
+ verifyTypescriptOutput(exampleSet);
// TODO: make detection more robust
if (exampleSet.name().contains("transient-0")) {
@@ -61,17 +62,24 @@ public class ExampleTests {
}
private Optional<Path> verifyJavaOutput(ExampleSet exampleSet) throws NoSuchAlgorithmException, IOException, InterruptedException {
- return verifyOutput(exampleSet, "java", List.of("mvn", "test"));
+ return verifyOutput(exampleSet, "java", List.of(List.of("mvn", "test")));
}
private Optional<Path> verifyRustOutput(ExampleSet exampleSet) throws NoSuchAlgorithmException, IOException, InterruptedException {
- return verifyOutput(exampleSet, "rust", List.of("cargo", "test"));
+ return verifyOutput(exampleSet, "rust", List.of(List.of("cargo", "test")));
+ }
+
+ private Optional<Path> verifyTypescriptOutput(ExampleSet exampleSet) throws NoSuchAlgorithmException, IOException, InterruptedException {
+ return verifyOutput(exampleSet, "typescript", List.of(
+ List.of("./node_modules/.bin/tsc", "--noEmit"),
+ List.of("npm", "test"))
+ );
}
private Optional<Path> verifyOutput(
ExampleSet exampleSet,
String name,
- List<String> command
+ List<List<String>> commands
) throws NoSuchAlgorithmException, IOException, InterruptedException {
var outputPath = exampleSet.path().resolve("output").resolve(name);
@@ -89,11 +97,14 @@ public class ExampleTests {
}
try {
- TestProcessRunner.command(command)
- .cwd(outputPath)
- .addEnvVar("HOBGOBLIN_OUTPUT_DIR", outputPath.toAbsolutePath().toString())
- .runCaptureOutput()
- .throwOnError();
+ for (var command : commands) {
+ TestProcessRunner.command(command)
+ .cwd(outputPath)
+ .addEnvVar("HOBGOBLIN_OUTPUT_DIR", outputPath.toAbsolutePath().toString())
+ .runCaptureOutput()
+ .throwOnError();
+ }
+
writeLastTestRun(lastTestRunPath, new LastTestRun(currentHash, true));
} catch (Throwable exception) {
writeLastTestRun(lastTestRunPath, new LastTestRun(currentHash, false));
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriterTests.java
index 8712b4a..71978f0 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriterTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriterTests.java
@@ -16,7 +16,7 @@ public class TypescriptWriterTests {
@Test
public void emptyModule() throws IOException {
- var typescript = new TypescriptModule();
+ var typescript = TypescriptModule.arbitrary().build();
var string = write(writer -> writer.writeModule(typescript));
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptIdentifierMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptIdentifierMatcher.java
new file mode 100644
index 0000000..d54b193
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptIdentifierMatcher.java
@@ -0,0 +1,41 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.typescript.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifierMatcher imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifierMatcher imports
+
+public final class TypescriptIdentifierMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> {
+ public static org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifierMatcher isTypescriptIdentifier() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifierMatcher(java.util.List.of());
+ }
+
+ private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier>> submatchers;
+
+ private TypescriptIdentifierMatcher(
+ java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier>> submatchers
+ ) {
+ this.submatchers = submatchers;
+ }
+
+ public org.zwobble.precisely.MatchResult match(java.lang.Object actual) {
+ return this.toMatcher().match(actual);
+ }
+
+ public org.zwobble.precisely.TextTree describe() {
+ return this.toMatcher().describe();
+ }
+
+ private org.zwobble.precisely.Matcher<java.lang.Object> toMatcher() {
+ return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier.class, this.submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifierMatcher withValue(org.zwobble.precisely.Matcher<? super String> value) {
+ var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier>>(this.submatchers);
+ submatchers.add(org.zwobble.precisely.Matchers.has("value", org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier::value, value));
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifierMatcher(submatchers);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifierMatcher body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifierMatcher body
+}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptModuleMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptModuleMatcher.java
index 088dba0..2a9f2f5 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptModuleMatcher.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptModuleMatcher.java
@@ -30,6 +30,12 @@ public final class TypescriptModuleMatcher implements org.zwobble.precisely.Matc
return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule.class, this.submatchers);
}
+ public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModuleMatcher withName(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptIdentifier>> name) {
+ var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule>>(this.submatchers);
+ submatchers.add(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModule::name, name));
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModuleMatcher(submatchers);
+ }
+
// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModuleMatcher body
// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptModuleMatcher body
}