Skip to content

Commit c1373e5

Browse files
Merge pull request #13 from samtkit/codegen
Codegen
2 parents c3010a0 + c35ead5 commit c1373e5

File tree

72 files changed

+4040
-169
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+4040
-169
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,10 @@ build
1414
ehthumbs.db
1515
Thumbs.db
1616

17+
# SAMT wrapper generated files #
18+
.samt
19+
samtw
20+
samtw.bat
21+
1722
# Random files used for debugging
1823
specification/examples/debug.samt

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ dependencies {
1414
kover(project(":cli"))
1515
kover(project(":language-server"))
1616
kover(project(":samt-config"))
17+
kover(project(":codegen"))
1718
}
1819

1920
koverReport {

cli/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ dependencies {
1414
implementation(project(":lexer"))
1515
implementation(project(":parser"))
1616
implementation(project(":semantic"))
17+
implementation(project(":samt-config"))
18+
implementation(project(":codegen"))
19+
implementation(project(":public-api"))
1720
}
1821

1922
application {

cli/src/main/kotlin/tools/samt/cli/CliArgs.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ class CliArgs {
1010

1111
@Parameters(commandDescription = "Compile SAMT files")
1212
class CompileCommand {
13-
@Parameter(description = "Files to compile, defaults to all .samt files in the current directory")
14-
var files: List<String> = mutableListOf()
13+
@Parameter(description = "SAMT project to compile, defaults to the 'samt.yaml' file in the current directory")
14+
var file: String = "./samt.yaml"
1515
}
1616

1717
@Parameters(commandDescription = "Dump SAMT files in various formats for debugging purposes")
@@ -25,8 +25,8 @@ class DumpCommand {
2525
@Parameter(names = ["--types"], description = "Dump a visual representation of the resolved types")
2626
var dumpTypes: Boolean = false
2727

28-
@Parameter(description = "Files to dump, defaults to all .samt files in the current directory")
29-
var files: List<String> = mutableListOf()
28+
@Parameter(description = "SAMT project to dump, defaults to the 'samt.yaml' file in the current directory")
29+
var file: String = "./samt.yaml"
3030
}
3131

3232
@Parameters(commandDescription = "Initialize or update the SAMT wrapper")

cli/src/main/kotlin/tools/samt/cli/CliCompiler.kt

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
package tools.samt.cli
22

3+
import tools.samt.codegen.Codegen
34
import tools.samt.common.DiagnosticController
45
import tools.samt.common.DiagnosticException
6+
import tools.samt.common.collectSamtFiles
7+
import tools.samt.common.readSamtSource
58
import tools.samt.lexer.Lexer
69
import tools.samt.parser.Parser
710
import tools.samt.semantic.SemanticModel
11+
import java.io.IOException
12+
import kotlin.io.path.isDirectory
13+
import kotlin.io.path.notExists
814

915
internal fun compile(command: CompileCommand, controller: DiagnosticController) {
10-
val sourceFiles = command.files.readSamtSourceFiles(controller)
16+
val (configuration ,_) = CliConfigParser.readConfig(command.file, controller) ?: return
17+
18+
if (configuration.source.notExists() || !configuration.source.isDirectory()) {
19+
controller.reportGlobalError("Source path '${configuration.source.toUri()}' does not point to valid directory")
20+
return
21+
}
22+
23+
val sourceFiles = collectSamtFiles(configuration.source.toUri()).readSamtSource(controller)
1124

1225
if (controller.hasErrors()) {
1326
return
@@ -40,7 +53,24 @@ internal fun compile(command: CompileCommand, controller: DiagnosticController)
4053
}
4154

4255
// build up the semantic model from the AST
43-
SemanticModel.build(fileNodes, controller)
56+
val model = SemanticModel.build(fileNodes, controller)
4457

45-
// Code Generators will be called here
58+
// if the semantic model failed to build, exit
59+
if (controller.hasErrors()) {
60+
return
61+
}
62+
63+
if (configuration.generators.isEmpty()) {
64+
controller.reportGlobalInfo("No generators configured, did you forget to add a 'generators' section to the 'samt.yaml' configuration?")
65+
return
66+
}
67+
68+
for (generator in configuration.generators) {
69+
val files = Codegen.generate(model, generator, controller)
70+
try {
71+
OutputWriter.write(generator.output, files)
72+
} catch (e: IOException) {
73+
controller.reportGlobalError("Failed to write output for generator '${generator.name}': ${e.message}")
74+
}
75+
}
4676
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package tools.samt.cli
2+
3+
import tools.samt.common.DiagnosticController
4+
import tools.samt.common.SamtConfiguration
5+
import tools.samt.common.SamtLinterConfiguration
6+
import tools.samt.config.SamtConfigurationParser
7+
import java.nio.file.InvalidPathException
8+
import kotlin.io.path.Path
9+
import kotlin.io.path.notExists
10+
11+
internal object CliConfigParser {
12+
fun readConfig(file: String, controller: DiagnosticController): Pair<SamtConfiguration, SamtLinterConfiguration>? {
13+
val configFile = try {
14+
Path(file)
15+
} catch (e: InvalidPathException) {
16+
controller.reportGlobalError("Invalid path '${file}': ${e.message}")
17+
return null
18+
}
19+
if (configFile.notExists()) {
20+
controller.reportGlobalInfo("Configuration file '${configFile.toUri()}' does not exist, using default configuration")
21+
}
22+
val configuration = try {
23+
SamtConfigurationParser.parseConfiguration(configFile)
24+
} catch (e: Exception) {
25+
controller.reportGlobalError("Failed to parse configuration file '${configFile.toUri()}': ${e.message}")
26+
return null
27+
}
28+
val samtLintConfigFile = configFile.resolveSibling(".samtrc.yaml")
29+
if (samtLintConfigFile.notExists()) {
30+
controller.reportGlobalInfo("Lint configuration file '${samtLintConfigFile.toUri()}' does not exist, using default lint configuration")
31+
}
32+
val linterConfiguration = try {
33+
SamtConfigurationParser.parseLinterConfiguration(samtLintConfigFile)
34+
} catch (e: Exception) {
35+
controller.reportGlobalError("Failed to parse lint configuration file '${samtLintConfigFile.toUri()}': ${e.message}")
36+
return null
37+
}
38+
39+
return Pair(configuration, linterConfiguration)
40+
}
41+
}

cli/src/main/kotlin/tools/samt/cli/CliDumper.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,27 @@ package tools.samt.cli
33
import com.github.ajalt.mordant.terminal.Terminal
44
import tools.samt.common.DiagnosticController
55
import tools.samt.common.DiagnosticException
6+
import tools.samt.common.collectSamtFiles
7+
import tools.samt.common.readSamtSource
68
import tools.samt.lexer.Lexer
79
import tools.samt.parser.Parser
810
import tools.samt.semantic.SemanticModel
11+
import kotlin.io.path.isDirectory
12+
import kotlin.io.path.notExists
913

1014
internal fun dump(command: DumpCommand, terminal: Terminal, controller: DiagnosticController) {
11-
val sourceFiles = command.files.readSamtSourceFiles(controller)
15+
val (configuration ,_) = CliConfigParser.readConfig(command.file, controller) ?: return
16+
17+
if (configuration.source.notExists() || !configuration.source.isDirectory()) {
18+
controller.reportGlobalError("Source path '${configuration.source.toUri()}' does not point to valid directory")
19+
return
20+
}
21+
22+
val sourceFiles = collectSamtFiles(configuration.source.toUri()).readSamtSource(controller)
23+
24+
if (controller.hasErrors()) {
25+
return
26+
}
1227

1328
if (controller.hasErrors()) {
1429
return

cli/src/main/kotlin/tools/samt/cli/CliFileResolution.kt

Lines changed: 0 additions & 12 deletions
This file was deleted.

cli/src/main/kotlin/tools/samt/cli/DiagnosticFormatter.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ internal class DiagnosticFormatter(
1515
companion object {
1616
private const val CONTEXT_ROW_COUNT = 3
1717

18-
// FIXME: this is a bit of a hack to get the terminal width
19-
// it also means we're assuming this output will only ever be printed in a terminal
20-
// i don't actually know what happens if it doesn't run in a tty setting
2118
fun format(controller: DiagnosticController, startTimestamp: Long, currentTimestamp: Long, terminalWidth: Int = Terminal().info.width): String {
2219
val formatter = DiagnosticFormatter(controller, startTimestamp, currentTimestamp, terminalWidth)
2320
return formatter.format()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package tools.samt.cli
2+
3+
import tools.samt.api.plugin.CodegenFile
4+
import java.io.IOException
5+
import java.nio.file.InvalidPathException
6+
import java.nio.file.Path
7+
import kotlin.io.path.*
8+
9+
internal object OutputWriter {
10+
@Throws(IOException::class)
11+
fun write(outputDirectory: Path, files: List<CodegenFile>) {
12+
if (!outputDirectory.exists()) {
13+
try {
14+
outputDirectory.createDirectories()
15+
} catch (e: IOException) {
16+
throw IOException("Failed to create output directory '${outputDirectory}'", e)
17+
}
18+
}
19+
if (!outputDirectory.isDirectory()) {
20+
throw IOException("Path '${outputDirectory}' does not point to a directory")
21+
}
22+
for (file in files) {
23+
val outputFile = try {
24+
outputDirectory.resolve(file.filepath)
25+
} catch (e: InvalidPathException) {
26+
throw IOException("Invalid path '${file.filepath}'", e)
27+
}
28+
try {
29+
outputFile.parent.createDirectories()
30+
if (outputFile.notExists()) {
31+
outputFile.createFile()
32+
}
33+
outputFile.writeText(file.source)
34+
} catch (e: IOException) {
35+
throw IOException("Failed to write file '${outputFile.toUri()}'", e)
36+
}
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)