Skip to content

Commit

Permalink
feat: version code action support major and major.minor version refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
washanhanzi committed Oct 23, 2024
1 parent 813c946 commit 73a4232
Showing 1 changed file with 102 additions and 122 deletions.
224 changes: 102 additions & 122 deletions src/controller/code_action.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::collections::HashMap;
use std::{collections::HashMap, fmt::Display};

use cargo::util::OptVersionReq;
use tower_lsp::lsp_types::{
CodeAction, CodeActionKind, CodeActionResponse, TextEdit, Url, WorkspaceEdit,
CodeAction, CodeActionKind, CodeActionResponse, Range, TextEdit, Url, WorkspaceEdit,
};

use crate::{
Expand All @@ -28,161 +29,120 @@ pub fn code_action_dependency(
DependencyEntryKind::SimpleDependency | DependencyEntryKind::TableDependencyVersion => {
let mut actions: CodeActionResponse = vec![];
let version_deco = version_decoration(dep);
if version_deco == VersionDecoration::Latest {
return None;
}
let latest = dep.latest_summary.as_ref().map(|s| s.version());
let latest_matched = dep.latest_matched_summary.as_ref().map(|s| s.version());
//TODO check user input is precise or not?
// dep.unresolved.unwrap().version_req();
//check version req contain minor or patch
// if the version req contain minor, provide a code action with version only contain major version
// if the version req contain patch, provide a code action with version only contain major and minor version
let mut major_code_action = false;
let mut minor_code_action = false;
match dep.unresolved.as_ref().unwrap().version_req() {
OptVersionReq::Req(req) => {
for r in &req.comparators {
if r.minor.is_some() {
major_code_action = true;
}
if r.minor.is_none() {
minor_code_action = true;
}
if r.patch.is_some() {
major_code_action = true;
minor_code_action = true;
}
}
}
_ => return None,
};
//TODO refactor
match version_deco {
VersionDecoration::Latest => return None,
VersionDecoration::Latest => {
let v = latest?;
if major_code_action {
actions.push(
make_code_action(
uri.clone(),
v.major,
CodeActionKind::REFACTOR,
node.range,
)
.into(),
);
}
if minor_code_action {
actions.push(
make_code_action(
uri.clone(),
format!("{}.{}", v.major, v.minor),
CodeActionKind::REFACTOR,
node.range,
)
.into(),
);
}
}
VersionDecoration::Local => return None,
VersionDecoration::NotInstalled => return None,
VersionDecoration::MixedUpgradeable => {
if let Some(v) = latest_matched {
let latest_matched = format!("\"{}\"", v);
actions.push(
CodeAction {
title: v.major.to_string(),
kind: Some(CodeActionKind::QUICKFIX),
diagnostics: None,
edit: Some(WorkspaceEdit {
changes: Some(HashMap::from([(
uri.clone(),
vec![TextEdit {
new_text: latest_matched,
range: node.range,
}],
)])),
document_changes: None,
change_annotations: None,
}),
..Default::default()
}
.into(),
make_code_action(uri.clone(), v, CodeActionKind::QUICKFIX, node.range)
.into(),
);
}
if let Some(v) = latest {
let latest = format!("\"{}\"", v);
actions.push(
CodeAction {
title: v.major.to_string(),
kind: Some(CodeActionKind::QUICKFIX),
diagnostics: None,
edit: Some(WorkspaceEdit {
changes: Some(HashMap::from([(
uri.clone(),
vec![TextEdit {
new_text: latest,
range: node.range,
}],
)])),
document_changes: None,
change_annotations: None,
}),
..Default::default()
}
.into(),
make_code_action(uri.clone(), v, CodeActionKind::QUICKFIX, node.range)
.into(),
);
}
}
VersionDecoration::CompatibleLatest => {
if let Some(v) = latest_matched {
let latest_matched = format!("\"{}\"", v);
let v = latest?;
if major_code_action {
actions.push(
CodeAction {
title: v.to_string(),
kind: Some(CodeActionKind::QUICKFIX),
diagnostics: None,
edit: Some(WorkspaceEdit {
changes: Some(HashMap::from([(
uri.clone(),
vec![TextEdit {
new_text: latest_matched,
range: node.range,
}],
)])),
document_changes: None,
change_annotations: None,
}),
..Default::default()
}
make_code_action(
uri.clone(),
v.major,
CodeActionKind::REFACTOR,
node.range,
)
.into(),
);
}
if minor_code_action {
actions.push(
make_code_action(
uri.clone(),
format!("{}.{}", v.major, v.minor),
CodeActionKind::REFACTOR,
node.range,
)
.into(),
);
}
actions.push(
make_code_action(uri.clone(), v, CodeActionKind::QUICKFIX, node.range)
.into(),
);
}
VersionDecoration::NoncompatibleLatest => {
if let Some(v) = latest {
let latest = format!("\"{}\"", v);
actions.push(
CodeAction {
title: v.to_string(),
kind: Some(CodeActionKind::QUICKFIX),
diagnostics: None,
edit: Some(WorkspaceEdit {
changes: Some(HashMap::from([(
uri,
vec![TextEdit {
new_text: latest,
range: node.range,
}],
)])),
document_changes: None,
change_annotations: None,
}),
..Default::default()
}
.into(),
make_code_action(uri.clone(), v, CodeActionKind::QUICKFIX, node.range)
.into(),
);
}
}
VersionDecoration::Yanked => {
if let Some(v) = latest {
let latest = format!("\"{}\"", v);
actions.push(
CodeAction {
title: v.to_string(),
kind: Some(CodeActionKind::QUICKFIX),
diagnostics: None,
edit: Some(WorkspaceEdit {
changes: Some(HashMap::from([(
uri.clone(),
vec![TextEdit {
new_text: latest,
range: node.range,
}],
)])),
document_changes: None,
change_annotations: None,
}),
..Default::default()
}
.into(),
make_code_action(uri.clone(), v, CodeActionKind::QUICKFIX, node.range)
.into(),
);
}
if let Some(v) = latest_matched {
let latest_matched = format!("\"{}\"", v);
actions.push(
CodeAction {
title: v.to_string(),
kind: Some(CodeActionKind::QUICKFIX),
diagnostics: None,
edit: Some(WorkspaceEdit {
changes: Some(HashMap::from([(
uri,
vec![TextEdit {
new_text: latest_matched,
range: node.range,
}],
)])),
document_changes: None,
change_annotations: None,
}),
..Default::default()
}
.into(),
make_code_action(uri, v, CodeActionKind::QUICKFIX, node.range).into(),
);
}
}
Expand All @@ -194,3 +154,23 @@ pub fn code_action_dependency(
_ => None,
}
}

fn make_code_action(uri: Url, v: impl Display, kind: CodeActionKind, range: Range) -> CodeAction {
CodeAction {
title: v.to_string(),
kind: Some(kind),
diagnostics: None,
edit: Some(WorkspaceEdit {
changes: Some(HashMap::from([(
uri,
vec![TextEdit {
new_text: format!("\"{}\"", v),
range,
}],
)])),
document_changes: None,
change_annotations: None,
}),
..Default::default()
}
}

0 comments on commit 73a4232

Please sign in to comment.