Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

textDocument/documentSymbol request (Outline) #114

Closed
wants to merge 11 commits into from
3 changes: 2 additions & 1 deletion vhdl_lang/src/analysis/concurrent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2019, Olof Kraigher [email protected]
// Copyright (c) 2021, Olof Kraigher [email protected]

// These fields are better explicit than .. since we are forced to consider if new fields should be searched
#![allow(clippy::unneeded_field_pattern)]
Expand Down Expand Up @@ -65,6 +65,7 @@ impl<'a> AnalyzeContext<'a> {
sensitivity_list,
decl,
statements,
source_range: _,
} = process;
if let Some(sensitivity_list) = sensitivity_list {
match sensitivity_list {
Expand Down
23 changes: 12 additions & 11 deletions vhdl_lang/src/analysis/design_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2019, Olof Kraigher [email protected]
// Copyright (c) 2021, Olof Kraigher [email protected]

use super::*;
use crate::ast::*;
Expand Down Expand Up @@ -75,14 +75,15 @@ impl<'a> AnalyzeContext<'a> {
);

if let Some(ref mut list) = unit.generic_clause {
self.analyze_interface_list(&mut primary_region, list, diagnostics)?;
self.analyze_interface_list(&mut primary_region, &mut list.item, diagnostics)?;
}
if let Some(ref mut list) = unit.port_clause {
self.analyze_interface_list(&mut primary_region, list, diagnostics)?;
self.analyze_interface_list(&mut primary_region, &mut list.item, diagnostics)?;
}
self.analyze_declarative_part(&mut primary_region, &mut unit.decl.item, diagnostics)?;
if let Some(ref mut statements) = unit.statements {
self.analyze_concurrent_part(&mut primary_region, &mut statements.item, diagnostics)?;
}
self.analyze_declarative_part(&mut primary_region, &mut unit.decl, diagnostics)?;
self.analyze_concurrent_part(&mut primary_region, &mut unit.statements, diagnostics)?;

*region = primary_region.without_parent();

Ok(())
Expand Down Expand Up @@ -148,9 +149,9 @@ impl<'a> AnalyzeContext<'a> {
);

if let Some(ref mut list) = unit.generic_clause {
self.analyze_interface_list(&mut primary_region, list, diagnostics)?;
self.analyze_interface_list(&mut primary_region, &mut list.item, diagnostics)?;
}
self.analyze_declarative_part(&mut primary_region, &mut unit.decl, diagnostics)?;
self.analyze_declarative_part(&mut primary_region, &mut unit.decl.item, diagnostics)?;

if !self.has_package_body() {
primary_region.close(diagnostics);
Expand Down Expand Up @@ -241,8 +242,8 @@ impl<'a> AnalyzeContext<'a> {
)),
);

self.analyze_declarative_part(&mut region, &mut unit.decl, diagnostics)?;
self.analyze_concurrent_part(&mut region, &mut unit.statements, diagnostics)?;
self.analyze_declarative_part(&mut region, &mut unit.decl.item, diagnostics)?;
self.analyze_concurrent_part(&mut region, &mut unit.statements.item, diagnostics)?;
region.close(diagnostics);
Ok(())
}
Expand Down Expand Up @@ -278,7 +279,7 @@ impl<'a> AnalyzeContext<'a> {

let mut region = Region::extend(&package.result().region, Some(&root_region));

self.analyze_declarative_part(&mut region, &mut unit.decl, diagnostics)?;
self.analyze_declarative_part(&mut region, &mut unit.decl.item, diagnostics)?;
region.close(diagnostics);
Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion vhdl_lang/src/analysis/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,10 +387,10 @@ impl DesignRoot {

let result = AnalysisData {
diagnostics,
has_circular_dependency,
root_region,
region,
ent,
has_circular_dependency,
};

unit.finish(result)
Expand Down
6 changes: 3 additions & 3 deletions vhdl_lang/src/analysis/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ pub enum AssignmentType {
}

impl AssignmentType {
fn to_str(&self) -> &str {
fn to_str(self) -> String {
match self {
AssignmentType::Signal => "signal",
AssignmentType::Variable => "variable",
AssignmentType::Signal => String::from("signal"),
AssignmentType::Variable => String::from("variable"),
}
}
}
Expand Down
21 changes: 9 additions & 12 deletions vhdl_lang/src/analysis/visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,26 +203,23 @@ impl<'a> Visible<'a> {
);

fn last_visible_pos(visible_entity: &VisibleEntityRef) -> u32 {
for pos in visible_entity.visible_pos.iter().rev() {
if let Some(pos) = pos {
return pos.range().start.line;
}
if let Some(pos) = visible_entity.visible_pos.iter().flatten().last() {
pos.range().start.line
} else {
0
}
0
}

// Sort by last visible pos to make error messages and testing deterministic
let mut visible_entities: Vec<_> = self.visible_entities.values().collect();
visible_entities.sort_by_key(|ent| last_visible_pos(*ent));

for visible_entity in visible_entities {
for visible_pos in visible_entity.visible_pos.iter().rev() {
if let Some(pos) = visible_pos {
error.add_related(
pos,
format!("Conflicting name '{}' made visible here", designator),
);
}
for visible_pos in visible_entity.visible_pos.iter().rev().flatten() {
error.add_related(
visible_pos,
format!("Conflicting name '{}' made visible here", designator),
);
}
if let Some(pos) = visible_entity.entity.decl_pos() {
error.add_related(
Expand Down
47 changes: 37 additions & 10 deletions vhdl_lang/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2018, Olof Kraigher [email protected]
// Copyright (c) 2021, Olof Kraigher [email protected]

// Allowing this, since box_patterns are feature gated: https://github.com/rust-lang/rfcs/pull/469
// Track here: https://github.com/rust-lang/rust/issues/29641
Expand Down Expand Up @@ -873,6 +873,9 @@ pub struct BlockStatement {
pub header: BlockHeader,
pub decl: Vec<Declaration>,
pub statements: Vec<LabeledConcurrentStatement>,

// Non-LRM fields
pub source_range: SrcPos,
}

/// LRM 11.2 Block statement
Expand All @@ -897,6 +900,9 @@ pub struct ProcessStatement {
pub sensitivity_list: Option<SensitivityList>,
pub decl: Vec<Declaration>,
pub statements: Vec<LabeledSequentialStatement>,

// Non-LRM fields
pub source_range: SrcPos,
}

/// LRM 11.4 Concurrent procedure call statements
Expand Down Expand Up @@ -1011,6 +1017,9 @@ pub enum ContextItem {
pub struct ContextDeclaration {
pub ident: Ident,
pub items: ContextClause,

// Non-LRM fields
pub source_range: SrcPos,
}

/// LRM 4.9 Package instatiation declaration
Expand All @@ -1020,6 +1029,9 @@ pub struct PackageInstantiation {
pub ident: Ident,
pub package_name: WithPos<SelectedName>,
pub generic_map: Option<Vec<AssociationElement>>,

// Non-LRM fields
pub source_range: SrcPos,
}

/// LRM 7.3 Configuration specification
Expand Down Expand Up @@ -1107,17 +1119,23 @@ pub struct ConfigurationDeclaration {
pub decl: Vec<ConfigurationDeclarativeItem>,
pub vunit_bind_inds: Vec<VUnitBindingIndication>,
pub block_config: BlockConfiguration,

// Non-LRM fields
pub source_range: SrcPos,
}

/// LRM 3.2 Entity declarations
#[derive(PartialEq, Debug, Clone)]
pub struct EntityDeclaration {
pub context_clause: ContextClause,
pub ident: Ident,
pub generic_clause: Option<Vec<InterfaceDeclaration>>,
pub port_clause: Option<Vec<InterfaceDeclaration>>,
pub decl: Vec<Declaration>,
pub statements: Vec<LabeledConcurrentStatement>,
pub generic_clause: Option<WithPos<Vec<InterfaceDeclaration>>>,
pub port_clause: Option<WithPos<Vec<InterfaceDeclaration>>>,
pub decl: WithPos<Vec<Declaration>>,
pub statements: Option<WithPos<Vec<LabeledConcurrentStatement>>>,

// Non-LRM fields
pub source_range: SrcPos,
}

/// LRM 3.3 Architecture bodies
Expand All @@ -1126,25 +1144,34 @@ pub struct ArchitectureBody {
pub context_clause: ContextClause,
pub ident: Ident,
pub entity_name: WithRef<Ident>,
pub decl: Vec<Declaration>,
pub statements: Vec<LabeledConcurrentStatement>,
pub decl: WithPos<Vec<Declaration>>,
pub statements: WithPos<Vec<LabeledConcurrentStatement>>,

// Non-LRM fields
pub source_range: SrcPos,
}

/// LRM 4.7 Package declarations
#[derive(PartialEq, Debug, Clone)]
pub struct PackageDeclaration {
pub context_clause: ContextClause,
pub ident: Ident,
pub generic_clause: Option<Vec<InterfaceDeclaration>>,
pub decl: Vec<Declaration>,
pub generic_clause: Option<WithPos<Vec<InterfaceDeclaration>>>,
pub decl: WithPos<Vec<Declaration>>,

// Non-LRM fields
pub source_range: SrcPos,
}

/// LRM 4.8 Package bodies
#[derive(PartialEq, Debug, Clone)]
pub struct PackageBody {
pub context_clause: ContextClause,
pub ident: WithRef<Ident>,
pub decl: Vec<Declaration>,
pub decl: WithPos<Vec<Declaration>>,

// Non-LRM fields
pub source_range: SrcPos,
}

/// LRM 13.1 Design units
Expand Down
8 changes: 4 additions & 4 deletions vhdl_lang/src/ast/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2018, Olof Kraigher [email protected]
// Copyright (c) 2021, Olof Kraigher [email protected]

//! Implementation of Display

Expand Down Expand Up @@ -1039,7 +1039,7 @@ impl Display for EntityDeclaration {

if let Some(generic_clause) = &self.generic_clause {
let mut first = true;
for generic in generic_clause {
for generic in &generic_clause.item {
if first {
write!(f, "\n generic (\n {}", generic)?;
} else {
Expand All @@ -1054,7 +1054,7 @@ impl Display for EntityDeclaration {

if let Some(port_clause) = &self.port_clause {
let mut first = true;
for port in port_clause {
for port in &port_clause.item {
if first {
write!(f, "\n port (\n {}", port)?;
} else {
Expand All @@ -1078,7 +1078,7 @@ impl Display for PackageDeclaration {
write!(f, "package {} is", self.ident)?;

let mut first = true;
for generic in generic_clause {
for generic in &generic_clause.item {
if first {
write!(f, "\n generic (\n {}", generic)?;
} else {
Expand Down
8 changes: 2 additions & 6 deletions vhdl_lang/src/ast/name_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,12 +332,8 @@ impl FunctionCall {
ref name,
ref parameters,
} = self;

if let Some(indexes) = assoc_elems_to_indexes(parameters) {
Some(Name::Indexed(Box::new(name.clone()), indexes))
} else {
None
}
assoc_elems_to_indexes(parameters)
.map(|indexes| Name::Indexed(Box::new(name.clone()), indexes))
}
}

Expand Down
10 changes: 9 additions & 1 deletion vhdl_lang/src/ast/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2019, Olof Kraigher [email protected]
// Copyright (c) 2021, Olof Kraigher [email protected]

// These fields are better explicit than .. since we are forced to consider if new fields should be searched
#![allow(clippy::unneeded_field_pattern)]
Expand Down Expand Up @@ -134,6 +134,13 @@ impl<T: Search> Search for Vec<T> {
}
}

impl<T: Search> Search for WithPos<Vec<T>> {
fn search(&self, searcher: &mut impl Searcher) -> SearchResult {
return_if_found!(&self.item.search(searcher));
NotFound
}
}

impl<T: Search> Search for Option<T> {
fn search(&self, searcher: &mut impl Searcher) -> SearchResult {
for decl in self.iter() {
Expand Down Expand Up @@ -423,6 +430,7 @@ impl Search for LabeledConcurrentStatement {
sensitivity_list,
decl,
statements,
source_range: _,
} = process;
return_if_found!(sensitivity_list.search(searcher));
return_if_found!(decl.search(searcher));
Expand Down
5 changes: 1 addition & 4 deletions vhdl_lang/src/data/contents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,13 @@ fn split_lines(code: &str) -> Vec<String> {
while i < bytes.len() {
let byte = bytes[i];

i += 1;
if byte == b'\n' {
i += 1;
let line = bytes[start..i].to_owned();
let line = unsafe { String::from_utf8_unchecked(line) };
lines.push(line);
start = i;
} else if byte == b'\r' {
i += 1;
let mut line = bytes[start..i].to_owned();
let last = line.len().saturating_sub(1);
line[last] = b'\n';
Expand All @@ -155,8 +154,6 @@ fn split_lines(code: &str) -> Vec<String> {
}

start = i;
} else {
i += 1;
}
}

Expand Down
2 changes: 1 addition & 1 deletion vhdl_lang/src/data/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl Diagnostic {

pub fn drain_related(&mut self) -> Vec<Diagnostic> {
let mut diagnostics = Vec::with_capacity(self.related.len());
let related = std::mem::replace(&mut self.related, Vec::new());
let related = std::mem::take(&mut self.related);
for (pos, msg) in related {
diagnostics.push(Diagnostic::new(
pos,
Expand Down
Loading