use crate::convert;
use rite_resolver::SpanMap;
use tower_lsp_server::ls_types::{GotoDefinitionResponse, Location, Position, Uri};
pub fn goto_definition_at(
span_map: &SpanMap,
pos: Position,
uri: &Uri,
) -> Option<GotoDefinitionResponse> {
let line = pos.line as usize + 1;
let col = pos.character as usize + 1;
let target = span_map.find_target_at(line, col)?;
let decl_span = span_map.declaration_span(target)?;
let target_pos = convert::span_to_position(decl_span);
Some(GotoDefinitionResponse::Scalar(Location {
uri: uri.clone(),
range: convert::point_range(target_pos),
}))
}
#[cfg(test)]
mod tests {
use super::*;
use rite_model::{ArtifactId, StepId};
use rite_resolver::{ReferenceContext, ReferenceEntry, ReferenceTarget, Span};
fn make_uri() -> Uri {
"file:///test.yaml".parse().unwrap()
}
#[test]
fn artifact_reference_resolves_to_creates_site() {
let mut span_map = SpanMap::default();
let creates_span = Span {
line: 5,
column: 7,
length: Some(20),
};
span_map
.artifacts
.insert(ArtifactId::new("keypair"), creates_span);
span_map.references.push(ReferenceEntry {
span: Span {
line: 12,
column: 14,
length: Some(20),
},
target: ReferenceTarget::Artifact(ArtifactId::new("keypair")),
context: ReferenceContext::Step(StepId::new("use_step")),
value: "${artifact.keypair}".to_string(),
});
let pos = Position {
line: 11, character: 14,
};
let resp = goto_definition_at(&span_map, pos, &make_uri())
.expect("should resolve artifact reference");
let GotoDefinitionResponse::Scalar(loc) = resp else {
panic!("expected Scalar response");
};
assert_eq!(loc.range.start.line, 4); }
}