Skip to content

Commit 84269c3

Browse files
authored
Enable configuring severities (#283)
1 parent ce2d47a commit 84269c3

Some content is hidden

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

62 files changed

+816
-679
lines changed

Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,19 @@ UNISIM.files = [
157157
'C:\Xilinx\Vivado\2023.1\data\vhdl\src\unisims\unisim_VCOMP.vhd',
158158
]
159159
UNISIM.is_third_party = true
160+
161+
[lint]
162+
unused = 'error' # Upgrade the 'unused' diagnostic to the 'error' severity
163+
unnecessary_work_library = false # Disable linting for the 'library work;' statement
160164
```
161165

166+
Using the `lint` table, you can configure the severity of diagnostics or turn of diagnostics altogether.
167+
168+
> [!WARNING]
169+
> You can overwrite every diagnostic error code including syntax or analysis errors using the lint table.
170+
> However, the intended use-case is for lints only.
171+
> Overwriting syntax or analysis errors (e.g., error codes `unused` or `syntax`) can cause unwanted side effects
172+
162173
Paths in the `vhdl_ls.toml` can contain glob patterns (i.e., `.../*/`).
163174
On Unix machines, they can contain environment variables using the `$NAME` or `${NAME}` syntax.
164175
On Windows machines, use the `%NAME%` syntax to substitute environment variables.

vhdl_lang/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pinned_vec = "0"
2828
itertools = "0"
2929
subst = "0.3.0"
3030
strum = { version = "0.26.2", features = ["derive"] }
31+
enum-map = "2.7.3"
3132

3233
[dev-dependencies]
3334
tempfile = "3"

vhdl_lang/src/analysis/analyze.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ impl<'a> AnalyzeContext<'a> {
401401

402402
bail!(
403403
diagnostics,
404-
Diagnostic::error(
404+
Diagnostic::new(
405405
pos,
406406
format!("No architecture '{architecture_name}' for entity '{library_name}.{entity_name}'"),
407407
ErrorCode::Unresolved,
@@ -444,7 +444,7 @@ impl<'a> AnalyzeContext<'a> {
444444

445445
bail!(
446446
diagnostics,
447-
Diagnostic::error(
447+
Diagnostic::new(
448448
pos,
449449
format!("No primary unit '{primary_name}' within library '{library_name}'"),
450450
ErrorCode::Unresolved,

vhdl_lang/src/analysis/association.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ impl<'a> AnalyzeContext<'a> {
217217
// No match
218218
bail!(
219219
diagnostics,
220-
Diagnostic::error(
220+
Diagnostic::new(
221221
&fcall.name.pos,
222222
format!(
223223
"No function '{}' accepting {}",
@@ -280,11 +280,11 @@ impl<'a> AnalyzeContext<'a> {
280280
if is_positional {
281281
fail = true;
282282

283-
diagnostics.push(Diagnostic::error(
283+
diagnostics.add(
284284
formal,
285285
"Named arguments are not allowed before positional arguments",
286286
ErrorCode::NamedBeforePositional,
287-
));
287+
);
288288
}
289289
} else {
290290
is_positional = true;
@@ -327,7 +327,7 @@ impl<'a> AnalyzeContext<'a> {
327327
let formal = ResolvedFormal::new_basic(actual_idx, formal);
328328
result.push((&actual.pos, Some(formal)));
329329
} else {
330-
diagnostics.error(
330+
diagnostics.add(
331331
&actual.pos,
332332
"Unexpected extra argument",
333333
ErrorCode::TooManyArguments,
@@ -354,7 +354,7 @@ impl<'a> AnalyzeContext<'a> {
354354
Some(resolved_formal) => {
355355
if let Some((prev_pos, prev_formal)) = associated.get(&resolved_formal.idx) {
356356
if !(resolved_formal.is_partial && prev_formal.is_partial) {
357-
let mut diag = Diagnostic::error(
357+
let mut diag = Diagnostic::new(
358358
actual_pos,
359359
format!(
360360
"{} has already been associated",
@@ -384,7 +384,7 @@ impl<'a> AnalyzeContext<'a> {
384384
// Output ports are allowed to be unconnected
385385
|| (formal_region.typ == InterfaceType::Port && formal.is_out_or_inout_signal()))
386386
{
387-
let diagnostic = Diagnostic::error(
387+
let diagnostic = Diagnostic::new(
388388
error_pos,
389389
format!("No association of {}", formal.describe()),
390390
ErrorCode::Unassociated,
@@ -489,7 +489,7 @@ impl<'a> AnalyzeContext<'a> {
489489
let Some(name) =
490490
as_fatal(self.expression_as_name(expr, scope, actual_pos, diagnostics))?
491491
else {
492-
diagnostics.error(
492+
diagnostics.add(
493493
actual_pos,
494494
"Expression must be a name denoting a signal",
495495
ErrorCode::InterfaceModeMismatch,
@@ -500,7 +500,7 @@ impl<'a> AnalyzeContext<'a> {
500500
ObjectName { base, .. },
501501
) if base.class() == ObjectClass::Signal)
502502
{
503-
diagnostics.error(
503+
diagnostics.add(
504504
actual_pos,
505505
"Name must denote a signal name",
506506
ErrorCode::InterfaceModeMismatch,
@@ -511,7 +511,7 @@ impl<'a> AnalyzeContext<'a> {
511511
let Some(name) =
512512
as_fatal(self.expression_as_name(expr, scope, actual_pos, diagnostics))?
513513
else {
514-
diagnostics.error(
514+
diagnostics.add(
515515
actual_pos,
516516
"Expression must be a name denoting a variable or shared variable",
517517
ErrorCode::InterfaceModeMismatch,
@@ -522,7 +522,7 @@ impl<'a> AnalyzeContext<'a> {
522522
ObjectName { base, .. },
523523
) if base.class() == ObjectClass::Variable || base.class() == ObjectClass::SharedVariable)
524524
{
525-
diagnostics.error(
525+
diagnostics.add(
526526
actual_pos,
527527
"Name must denote a variable name",
528528
ErrorCode::InterfaceModeMismatch,
@@ -533,7 +533,7 @@ impl<'a> AnalyzeContext<'a> {
533533
let Some(name) =
534534
as_fatal(self.expression_as_name(expr, scope, actual_pos, diagnostics))?
535535
else {
536-
diagnostics.error(
536+
diagnostics.add(
537537
actual_pos,
538538
"Expression must be a name denoting a file",
539539
ErrorCode::InterfaceModeMismatch,
@@ -544,7 +544,7 @@ impl<'a> AnalyzeContext<'a> {
544544
ent.kind(),
545545
AnyEntKind::File(_) | AnyEntKind::InterfaceFile(_)
546546
)) {
547-
diagnostics.error(
547+
diagnostics.add(
548548
actual_pos,
549549
"Name must denote a file name",
550550
ErrorCode::InterfaceModeMismatch,
@@ -592,11 +592,11 @@ fn to_formal_conversion_argument(
592592

593593
impl Diagnostic {
594594
pub fn invalid_formal(pos: impl AsRef<SrcPos>) -> Diagnostic {
595-
Diagnostic::error(pos, "Invalid formal", ErrorCode::InvalidFormal)
595+
Diagnostic::new(pos, "Invalid formal", ErrorCode::InvalidFormal)
596596
}
597597

598598
pub fn invalid_formal_conversion(pos: impl AsRef<SrcPos>) -> Diagnostic {
599-
Diagnostic::error(
599+
Diagnostic::new(
600600
pos,
601601
"Invalid formal conversion",
602602
ErrorCode::InvalidFormalConversion,
@@ -608,7 +608,7 @@ impl Diagnostic {
608608
from: BaseType,
609609
to: TypeEnt,
610610
) -> Diagnostic {
611-
Diagnostic::error(
611+
Diagnostic::new(
612612
pos,
613613
format!(
614614
"{} cannot be converted to {}",

vhdl_lang/src/analysis/concurrent.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ impl<'a> AnalyzeContext<'a> {
434434
diagnostics,
435435
))? {
436436
if object_name.base.class() != ObjectClass::Signal {
437-
diagnostics.error(
437+
diagnostics.add(
438438
&name.pos,
439439
format!(
440440
"{} is not a signal and cannot be in a sensitivity list",
@@ -444,7 +444,7 @@ impl<'a> AnalyzeContext<'a> {
444444
)
445445
} else if object_name.base.mode() == Some(Mode::Out) && !object_name.base.is_port()
446446
{
447-
diagnostics.error(
447+
diagnostics.add(
448448
&name.pos,
449449
format!(
450450
"{} cannot be in a sensitivity list",

vhdl_lang/src/analysis/declarative.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl<'a> AnalyzeContext<'a> {
117117
let (decl, remaining) = declarations[i..].split_first_mut().unwrap();
118118

119119
if !decl.is_allowed_in_context(parent.kind()) {
120-
diagnostics.error(
120+
diagnostics.add(
121121
decl.get_pos(self.ctx),
122122
format!("{} declaration not allowed here", decl.describe()),
123123
ErrorCode::DeclarationNotAllowed,
@@ -137,7 +137,7 @@ impl<'a> AnalyzeContext<'a> {
137137
(full_decl.ident.pos(), Some(full_decl.span))
138138
}
139139
None => {
140-
let error = Diagnostic::error(
140+
let error = Diagnostic::new(
141141
type_decl.ident.pos(),
142142
format!(
143143
"Missing full type declaration of incomplete type '{}'",
@@ -261,7 +261,7 @@ impl<'a> AnalyzeContext<'a> {
261261
if let Some(ref signature) = signature {
262262
diagnostics.push(Diagnostic::should_not_have_signature("Alias", signature));
263263
}
264-
diagnostics.error(
264+
diagnostics.add(
265265
&name.pos,
266266
format!("{} cannot be aliased", resolved_name.describe_type()),
267267
ErrorCode::MismatchedKinds,
@@ -636,7 +636,7 @@ impl<'a> AnalyzeContext<'a> {
636636
)?;
637637
attr_ent
638638
} else {
639-
diagnostics.error(
639+
diagnostics.add(
640640
&ident.item.pos,
641641
format!("{} is not an attribute", ent.describe()),
642642
ErrorCode::MismatchedKinds,
@@ -645,7 +645,7 @@ impl<'a> AnalyzeContext<'a> {
645645
}
646646
}
647647
Ok(NamedEntities::Overloaded(_)) => {
648-
diagnostics.error(
648+
diagnostics.add(
649649
&ident.item.pos,
650650
format!("Overloaded name '{}' is not an attribute", ident.item),
651651
ErrorCode::MismatchedKinds,
@@ -715,11 +715,11 @@ impl<'a> AnalyzeContext<'a> {
715715
let ent = ent.as_actual();
716716

717717
if Some(*entity_class) != get_entity_class(ent) {
718-
diagnostics.push(Diagnostic::error(
718+
diagnostics.add(
719719
designator,
720720
format!("{} is not of class {}", ent.describe(), entity_class),
721721
ErrorCode::MismatchedEntityClass,
722-
));
722+
);
723723
return Ok(());
724724
}
725725

@@ -729,11 +729,11 @@ impl<'a> AnalyzeContext<'a> {
729729
| EntityClass::Package
730730
| EntityClass::Configuration => {
731731
if ent != parent {
732-
diagnostics.push(Diagnostic::error(
732+
diagnostics.add(
733733
designator,
734734
"Attribute specification must be in the immediate declarative part",
735735
ErrorCode::MisplacedAttributeSpec,
736-
));
736+
);
737737
return Ok(());
738738
}
739739
}
@@ -750,11 +750,11 @@ impl<'a> AnalyzeContext<'a> {
750750
| EntityClass::File
751751
| EntityClass::Label => {
752752
if ent.parent != Some(parent) {
753-
diagnostics.push(Diagnostic::error(
753+
diagnostics.add(
754754
designator,
755755
"Attribute specification must be in the immediate declarative part",
756756
ErrorCode::MisplacedAttributeSpec,
757-
));
757+
);
758758
return Ok(());
759759
}
760760
}
@@ -938,7 +938,7 @@ impl Diagnostic {
938938
des: &Designator,
939939
overloaded: &OverloadedName,
940940
) -> Diagnostic {
941-
let mut diagnostic = Diagnostic::error(
941+
let mut diagnostic = Diagnostic::new(
942942
pos,
943943
format!(
944944
"Could not find declaration of {} with given signature",
@@ -951,15 +951,15 @@ impl Diagnostic {
951951
}
952952

953953
fn should_not_have_signature(prefix: &str, pos: impl AsRef<SrcPos>) -> Diagnostic {
954-
Diagnostic::error(
954+
Diagnostic::new(
955955
pos,
956956
format!("{prefix} should only have a signature for subprograms and enum literals"),
957957
ErrorCode::IllegalSignature,
958958
)
959959
}
960960

961961
fn signature_required(pos: impl AsRef<SrcPos>) -> Diagnostic {
962-
Diagnostic::error(
962+
Diagnostic::new(
963963
pos,
964964
"Signature required for alias of subprogram and enum literals",
965965
ErrorCode::SignatureRequired,

0 commit comments

Comments
 (0)