Add quickfix for unknown constructors.
This commit is contained in:
parent
f6eff7ec58
commit
c0513da032
|
@ -90,6 +90,22 @@ impl TypedModule {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_constructor(&self, name: &str) -> bool {
|
||||||
|
self.definitions.iter().any(|def| match def {
|
||||||
|
Definition::DataType(t) if t.public && !t.opaque => t
|
||||||
|
.constructors
|
||||||
|
.iter()
|
||||||
|
.any(|constructor| constructor.name == name),
|
||||||
|
Definition::DataType(_) => false,
|
||||||
|
Definition::Fn(_) => false,
|
||||||
|
Definition::TypeAlias(_) => false,
|
||||||
|
Definition::ModuleConstant(_) => false,
|
||||||
|
Definition::Use(_) => false,
|
||||||
|
Definition::Test(_) => false,
|
||||||
|
Definition::Validator(_) => false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn validate_module_name(&self) -> Result<(), Error> {
|
pub fn validate_module_name(&self) -> Result<(), Error> {
|
||||||
if self.name == "aiken" || self.name == "aiken/builtin" {
|
if self.name == "aiken" || self.name == "aiken/builtin" {
|
||||||
return Err(Error::ReservedModuleName {
|
return Err(Error::ReservedModuleName {
|
||||||
|
|
|
@ -131,10 +131,7 @@ impl ParsedDocument {
|
||||||
unqualified: &str,
|
unqualified: &str,
|
||||||
location: Span,
|
location: Span,
|
||||||
) -> AnnotatedEdit {
|
) -> AnnotatedEdit {
|
||||||
let title = format!(
|
let title = format!("Use '{}' from {}", unqualified, import.name);
|
||||||
"Insert new unqualified import '{}' to {}",
|
|
||||||
unqualified, import.name
|
|
||||||
);
|
|
||||||
(
|
(
|
||||||
title,
|
title,
|
||||||
insert_text(
|
insert_text(
|
||||||
|
@ -151,10 +148,7 @@ impl ParsedDocument {
|
||||||
unqualified: &str,
|
unqualified: &str,
|
||||||
location: Span,
|
location: Span,
|
||||||
) -> AnnotatedEdit {
|
) -> AnnotatedEdit {
|
||||||
let title = format!(
|
let title = format!("Use '{}' from {}", unqualified, import.name);
|
||||||
"Insert new unqualified import '{}' to {}",
|
|
||||||
unqualified, import.name
|
|
||||||
);
|
|
||||||
(
|
(
|
||||||
title,
|
title,
|
||||||
insert_text(
|
insert_text(
|
||||||
|
@ -171,10 +165,7 @@ impl ParsedDocument {
|
||||||
unqualified: &str,
|
unqualified: &str,
|
||||||
location: Span,
|
location: Span,
|
||||||
) -> AnnotatedEdit {
|
) -> AnnotatedEdit {
|
||||||
let title = format!(
|
let title = format!("Use '{}' from {}", unqualified, import.name);
|
||||||
"Add new unqualified import '{}' to {}",
|
|
||||||
unqualified, import.name
|
|
||||||
);
|
|
||||||
(
|
(
|
||||||
title,
|
title,
|
||||||
insert_text(
|
insert_text(
|
||||||
|
|
|
@ -5,13 +5,16 @@ use crate::{
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
const UNKNOWN_VARIABLE: &str = "aiken::check::unknown::variable";
|
const UNKNOWN_VARIABLE: &str = "aiken::check::unknown::variable";
|
||||||
const UNKNOWN_MODULE: &str = "aiken::check::unknown::module";
|
|
||||||
const UNKNOWN_TYPE: &str = "aiken::check::unknown::type";
|
const UNKNOWN_TYPE: &str = "aiken::check::unknown::type";
|
||||||
|
const UNKNOWN_CONSTRUCTOR: &str = "aiken::check::unknown::type_constructor";
|
||||||
|
const UNKNOWN_MODULE: &str = "aiken::check::unknown::module";
|
||||||
|
|
||||||
/// Errors for which we can provide quickfixes
|
/// Errors for which we can provide quickfixes
|
||||||
|
#[allow(clippy::enum_variant_names)]
|
||||||
pub enum Quickfix {
|
pub enum Quickfix {
|
||||||
UnknownIdentifier,
|
UnknownIdentifier,
|
||||||
UnknownModule,
|
UnknownModule,
|
||||||
|
UnknownConstructor,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_code(diagnostic: &lsp_types::Diagnostic, expected: &str) -> bool {
|
fn match_code(diagnostic: &lsp_types::Diagnostic, expected: &str) -> bool {
|
||||||
|
@ -35,6 +38,10 @@ pub fn assert(diagnostic: &lsp_types::Diagnostic) -> Option<Quickfix> {
|
||||||
return Some(Quickfix::UnknownIdentifier);
|
return Some(Quickfix::UnknownIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if match_code(diagnostic, UNKNOWN_CONSTRUCTOR) {
|
||||||
|
return Some(Quickfix::UnknownConstructor);
|
||||||
|
}
|
||||||
|
|
||||||
if match_code(diagnostic, UNKNOWN_MODULE) {
|
if match_code(diagnostic, UNKNOWN_MODULE) {
|
||||||
return Some(Quickfix::UnknownModule);
|
return Some(Quickfix::UnknownModule);
|
||||||
}
|
}
|
||||||
|
@ -55,6 +62,9 @@ pub fn quickfix(
|
||||||
let edits = match quickfix {
|
let edits = match quickfix {
|
||||||
Quickfix::UnknownIdentifier => unknown_identifier(compiler, parsed_document, data),
|
Quickfix::UnknownIdentifier => unknown_identifier(compiler, parsed_document, data),
|
||||||
Quickfix::UnknownModule => unknown_module(compiler, parsed_document, data),
|
Quickfix::UnknownModule => unknown_module(compiler, parsed_document, data),
|
||||||
|
Quickfix::UnknownConstructor => {
|
||||||
|
unknown_constructor(compiler, parsed_document, data)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (title, edit) in edits.into_iter() {
|
for (title, edit) in edits.into_iter() {
|
||||||
|
@ -99,6 +109,24 @@ fn unknown_identifier(
|
||||||
edits
|
edits
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unknown_constructor(
|
||||||
|
compiler: &LspProject,
|
||||||
|
parsed_document: &ParsedDocument,
|
||||||
|
constructor_name: &str,
|
||||||
|
) -> Vec<AnnotatedEdit> {
|
||||||
|
let mut edits = Vec::new();
|
||||||
|
|
||||||
|
for module in compiler.project.modules() {
|
||||||
|
if module.ast.has_constructor(constructor_name) {
|
||||||
|
if let Some(edit) = parsed_document.import(&module, Some(constructor_name)) {
|
||||||
|
edits.push(edit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
edits
|
||||||
|
}
|
||||||
|
|
||||||
fn unknown_module(
|
fn unknown_module(
|
||||||
compiler: &LspProject,
|
compiler: &LspProject,
|
||||||
parsed_document: &ParsedDocument,
|
parsed_document: &ParsedDocument,
|
||||||
|
|
Loading…
Reference in New Issue