Skip to content

Commit

Permalink
Rust: Ask cargo what the package root is.
Browse files Browse the repository at this point in the history
This patches a tiny edge case that might not show up in practice. The problem is that the Rust code is being generated into an existing project (i.e., there is already a Cargo.toml file in the src-gen directory), which means that sometimes srcGenPkgPath != the actual package root (according to cargo). The cost of collecting and parsing the metadata is probably not negligible, so it would be nice if we didn't have to do this.

See rust-lang/cargo#4933.
  • Loading branch information
petervdonovan committed Jan 12, 2022
1 parent c4ca40b commit ca212f2
Showing 1 changed file with 27 additions and 1 deletion.
28 changes: 27 additions & 1 deletion org.lflang/src/org/lflang/generator/rust/RustValidator.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.lflang.generator.rust

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import org.eclipse.lsp4j.DiagnosticSeverity
Expand Down Expand Up @@ -29,6 +30,14 @@ class RustValidator(
private val mapper = ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
private const val COMPILER_MESSAGE_REASON = "compiler-message"
}
// See the following reference for details on cargo metadata: https://doc.rust-lang.org/cargo/commands/cargo-metadata.html
private data class RustMetadata(
// Other fields exist, but we don't need them. The mapper is configured not to fail on unknown properties.
@JsonProperty("workspace_root") private val _workspaceRoot: String
) {
val workspaceRoot: Path
get() = Path.of(_workspaceRoot)
}
// See the following references for details on these data classes:
// * https://doc.rust-lang.org/cargo/reference/external-tools.html#json-messages
// * https://doc.rust-lang.org/rustc/json.html
Expand Down Expand Up @@ -105,6 +114,23 @@ class RustValidator(
@JsonProperty("highlight_end") val highlightEnd: Int
)

private var _metadata: RustMetadata? = null

private fun getMetadata(): RustMetadata? {
val nullableCommand = LFCommand.get("cargo", listOf("metadata", "--format-version", "1"), fileConfig.srcGenPkgPath)
_metadata = _metadata ?: nullableCommand?.let { command ->
command.run({false}, false)
command.output.toString().lines().filter { it.startsWith("{") }.mapNotNull {
try {
mapper.readValue(it, RustMetadata::class.java)
} catch (e: JsonProcessingException) {
null
}
}.firstOrNull()
}
return _metadata
}

override fun getPossibleStrategies(): Collection<ValidationStrategy> = listOf(object: ValidationStrategy {
override fun getCommand(generatedFile: Path?): LFCommand {
return LFCommand.get("cargo", listOf("clippy", "--message-format", "json"), fileConfig.srcGenPkgPath)
Expand All @@ -118,7 +144,7 @@ class RustValidator(
val message = mapper.readValue(messageLine, RustCompilerMessage::class.java).message
if (message.spans.isEmpty()) errorReporter.report(message.severity, message.message)
for (s: RustSpan in message.spans) {
val p: Path = fileConfig.srcGenPkgPath.resolve(s.fileName)
val p: Path? = getMetadata()?.workspaceRoot?.resolve(s.fileName)
map[p]?.let {
for (lfSourcePath: Path in it.lfSourcePaths()) {
errorReporter.report(
Expand Down

0 comments on commit ca212f2

Please sign in to comment.