Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
5 changes: 2 additions & 3 deletions crates/hir/src/hir_def/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,8 @@ impl_lower_declaration!(LowerBlockCtx<'_>, block, block_source_map);
impl LowerBlockCtx<'_> {
fn lower_struct_type(&mut self, struct_ty: ast::StructUnionType) -> StructId {
let container_id = ContainerId::BlockId(self.block_id);
let struct_def = lower_struct_def(struct_ty.clone(), container_id, |ty| {
self.expr_ctx().lower_data_ty(ty)
});
let struct_def =
lower_struct_def(struct_ty, container_id, |ty| self.expr_ctx().lower_data_ty(ty));

alloc_idx_and_src! {
struct_def => self.block.structs,
Expand Down
7 changes: 3 additions & 4 deletions crates/hir/src/hir_def/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,8 @@ impl LowerProc for LowerFileCtx<'_> {
impl LowerFileCtx<'_> {
fn lower_struct_type(&mut self, struct_ty: ast::StructUnionType) -> StructId {
let container_id = ContainerId::HirFileId(self.file_id);
let struct_def = lower_struct_def(struct_ty.clone(), container_id, |ty| {
self.expr_ctx().lower_data_ty(ty)
});
let struct_def =
lower_struct_def(struct_ty, container_id, |ty| self.expr_ctx().lower_data_ty(ty));

alloc_idx_and_src! {
struct_def => self.file.structs,
Expand Down Expand Up @@ -188,7 +187,7 @@ impl LowerFileCtx<'_> {
&mut self,
func: ast::FunctionDeclaration,
) -> Option<LocalSubroutineId> {
let src = SubroutineSrc::from(func.clone());
let src = SubroutineSrc::from(func);
let subroutine_def_id = self.db.intern_subroutine(SubroutineLoc {
cont_id: self.file_id.into(),
src: InFile::new(self.file_id, src),
Expand Down
7 changes: 3 additions & 4 deletions crates/hir/src/hir_def/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,8 @@ impl LowerProc for LowerModuleCtx<'_> {
impl LowerModuleCtx<'_> {
fn lower_struct_type(&mut self, struct_ty: ast::StructUnionType) -> StructId {
let container_id = ContainerId::ModuleId(self.module_id);
let struct_def = lower_struct_def(struct_ty.clone(), container_id, |ty| {
self.expr_ctx().lower_data_ty(ty)
});
let struct_def =
lower_struct_def(struct_ty, container_id, |ty| self.expr_ctx().lower_data_ty(ty));

alloc_idx_and_src! {
struct_def => self.module.structs,
Expand Down Expand Up @@ -273,7 +272,7 @@ impl LowerModuleCtx<'_> {
&mut self,
func: ast::FunctionDeclaration,
) -> Option<LocalSubroutineId> {
let src = SubroutineSrc::from(func.clone());
let src = SubroutineSrc::from(func);
let subroutine_def_id = self.db.intern_subroutine(SubroutineLoc {
cont_id: self.module_id.into(),
src: InFile::new(self.file_id, src),
Expand Down
5 changes: 2 additions & 3 deletions crates/hir/src/hir_def/subroutine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,8 @@ impl LowerSubroutineBodyCtx<'_> {

fn lower_struct_type(&mut self, struct_ty: ast::StructUnionType) -> StructId {
let container_id = self.container_id();
let struct_def = lower_struct_def(struct_ty.clone(), container_id, |ty| {
self.expr_ctx().lower_data_ty(ty)
});
let struct_def =
lower_struct_def(struct_ty, container_id, |ty| self.expr_ctx().lower_data_ty(ty));

alloc_idx_and_src! {
struct_def => self.subroutine.structs,
Expand Down
1 change: 0 additions & 1 deletion crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(trait_alias)]
#![feature(decl_macro)]

pub mod container;
Expand Down
2 changes: 1 addition & 1 deletion crates/hir/src/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl UnitScope {
for file_id in db.files().iter() {
let file_id = HirFileId(*file_id);
let file_scope = db.file_scope(file_id);
scope.entries.extend(file_scope.entries.clone().into_iter());
scope.entries.extend(file_scope.entries.clone());
}

Arc::new(scope)
Expand Down
2 changes: 1 addition & 1 deletion crates/ide-db/src/apply_change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl RootDb {
tracing::trace!("apply_change {:?}", change);

if let Some(roots) = &change.roots {
let (lib_roots, local_roots): (FxHashSet<_>, FxHashSet<_>) =
let (_lib_roots, _local_roots): (FxHashSet<_>, FxHashSet<_>) =
roots.iter().enumerate().partition_map(|(idx, root)| {
let source_root_id = SourceRootId(idx as u32);
if root.is_lib {
Expand Down
11 changes: 2 additions & 9 deletions crates/ide/src/code_action.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use hir::semantics::Semantics;
use ide_db::root_db::RootDb;
use syntax::{
SyntaxElement, SyntaxNodeExt, TokenAtOffset,
ast::{AstNode, CompilationUnit},
};
use syntax::ast::{AstNode, CompilationUnit};
use utils::text_edit::{TextRange, TextSize};
use vfs::FileId;

Expand Down Expand Up @@ -124,16 +121,12 @@ struct CodeActionCtx<'a> {
file_id: FileId,
range: TextRange,
compilation_unit: CompilationUnit<'a>,
token_at_offset: TokenAtOffset<'a>,
covering_element: SyntaxElement<'a>,
}

impl<'a> CodeActionCtx<'a> {
fn new(sema: &'a Semantics<'a, RootDb>, file_id: FileId, range: TextRange) -> Self {
let compilation_unit = sema.parse(file_id);
let token_at_offset = compilation_unit.syntax().token_at_offset(range.start());
let covering_element = compilation_unit.syntax().covering_element(range);
Self { sema, file_id, range, compilation_unit, token_at_offset, covering_element }
Self { sema, file_id, range, compilation_unit }
}

fn offset(&self) -> TextSize {
Expand Down
6 changes: 6 additions & 0 deletions crates/ide/src/completion/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ mod tests {
assert_eq!(c.lex, LexContext::PreprocDirective);
}

#[test]
fn detects_preproc_directive_at_boundary() {
let c = ctx("`define FOO/*caret*/\nmodule m; endmodule\n");
assert_eq!(c.lex, LexContext::PreprocDirective);
}

#[test]
fn detects_line_comment_at_eof_top_level() {
let c = ctx("// ,/*caret*/");
Expand Down
54 changes: 41 additions & 13 deletions crates/ide/src/completion/context/lex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,7 @@ pub(super) fn detect_lex_context(caret: &CaretSnapshot<'_>) -> LexContext {
return LexContext::StringLiteral;
}

if let Some(kind) = caret.root.trivia_kind_at_offset(caret.offset) {
let kind = if kind == syntax::Trivia![eol] {
// Also treat the end boundary of a line comment as being inside the comment.
line_comment_kind_before_offset(caret).unwrap_or(kind)
} else {
kind
};
if let Some(kind) = trivia_kind_at_caret_offset(caret) {
return match kind {
syntax::Trivia![lc] => LexContext::LineComment,
syntax::Trivia![bc] => LexContext::BlockComment,
Expand All @@ -23,8 +17,8 @@ pub(super) fn detect_lex_context(caret: &CaretSnapshot<'_>) -> LexContext {
};
}

if line_comment_kind_before_offset(caret).is_some() {
return LexContext::LineComment;
if is_inside_preproc_directive_trivia(caret) {
return LexContext::PreprocDirective;
}

if is_inside_preproc_directive_node(caret) {
Expand All @@ -34,13 +28,16 @@ pub(super) fn detect_lex_context(caret: &CaretSnapshot<'_>) -> LexContext {
LexContext::Code
}

fn line_comment_kind_before_offset(caret: &CaretSnapshot<'_>) -> Option<syntax::TriviaKind> {
// Also treat the end boundary of a line comment as being inside the comment.
// This covers the common case `// ...<caret>\n` where the cursor is right
// before the newline.
fn trivia_kind_at_caret_offset(caret: &CaretSnapshot<'_>) -> Option<syntax::TriviaKind> {
let kind = caret.root.trivia_kind_at_offset(caret.offset);
if !matches!(kind, Some(syntax::Trivia![eol]) | None) {
return kind;
}

if caret.offset == TextSize::new(0) {
return None;
}

let prev = caret.offset - TextSize::new(1);
let kind = caret.root.trivia_kind_at_offset(prev)?;
(kind == syntax::Trivia![lc]).then_some(kind)
Expand All @@ -54,6 +51,37 @@ fn is_inside_string_literal(caret: &CaretSnapshot<'_>) -> bool {
})
}

fn is_inside_preproc_directive_trivia(caret: &CaretSnapshot<'_>) -> bool {
fn token_has_covering_directive_trivia(
tok: syntax::SyntaxTokenWithParent<'_>,
offset: TextSize,
) -> bool {
tok.tok.trivias().any(|trivia| {
if trivia.kind() != syntax::Trivia!["`"] {
return false;
}

let Some(node) = trivia.syntax() else {
return false;
};
node.text_range().is_some_and(|range| range.contains(offset) || range.end() == offset)
})
}

if caret
.root
.token_after_or_at_offset(caret.offset)
.is_some_and(|tok| token_has_covering_directive_trivia(tok, caret.offset))
{
return true;
}

caret
.root
.token_before_offset(caret.offset)
.is_some_and(|tok| token_has_covering_directive_trivia(tok, caret.offset))
}

fn is_inside_preproc_directive_node(caret: &CaretSnapshot<'_>) -> bool {
let Some(node) = caret.covering_node() else {
return false;
Expand Down
16 changes: 8 additions & 8 deletions crates/ide/src/completion/context/syn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,16 @@ fn base_syn_context(caret: &CaretSnapshot<'_>) -> SynContext {
fn qualifier_after_dot(caret: &CaretSnapshot<'_>) -> Option<Qualifier> {
let offset = caret.offset;

if let Some(named) = caret.root.find_node_at_offset::<ast::NamedPortConnection<'_>>(offset) {
if named.dot_name_zone_contains(offset) {
return Some(Qualifier::AfterDot(AfterDot { kind: DotKind::NamedPort }));
}
if let Some(named) = caret.root.find_node_at_offset::<ast::NamedPortConnection<'_>>(offset)
&& named.dot_name_zone_contains(offset)
{
return Some(Qualifier::AfterDot(AfterDot { kind: DotKind::NamedPort }));
}

if let Some(named) = caret.root.find_node_at_offset::<ast::NamedParamAssignment<'_>>(offset) {
if named.dot_name_zone_contains(offset) {
return Some(Qualifier::AfterDot(AfterDot { kind: DotKind::NamedParam }));
}
if let Some(named) = caret.root.find_node_at_offset::<ast::NamedParamAssignment<'_>>(offset)
&& named.dot_name_zone_contains(offset)
{
return Some(Qualifier::AfterDot(AfterDot { kind: DotKind::NamedParam }));
}

let prev = caret.root.token_before_offset(offset)?;
Expand Down
16 changes: 8 additions & 8 deletions crates/ide/src/completion/engine/named.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ pub(super) fn complete_named_port_names(
sema.find_node_at_offset::<ast::HierarchicalInstance>(file.syntax(), position.offset)
{
for conn in instance.connections().children() {
if let Some(named) = conn.as_named_port_connection() {
if let Some(name) = lower_ident_opt(named.name()) {
used_named_ports.insert(name);
}
if let Some(named) = conn.as_named_port_connection()
&& let Some(name) = lower_ident_opt(named.name())
{
used_named_ports.insert(name);
}
}
}
Expand Down Expand Up @@ -99,10 +99,10 @@ pub(super) fn complete_named_param_names(
let mut used_named_params = FxHashSet::default();
if let Some(params) = instantiation.parameters() {
for assignment in params.parameters().children() {
if let Some(named) = assignment.as_named_param_assignment() {
if let Some(name) = lower_ident_opt(named.name()) {
used_named_params.insert(name);
}
if let Some(named) = assignment.as_named_param_assignment()
&& let Some(name) = lower_ident_opt(named.name())
{
used_named_params.insert(name);
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions crates/ide/src/completion/engine/paren_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ use syntax::{
ast::{self, AstNode},
has_text_range::HasTextRange,
};
use utils::get::Get;
use utils::text_edit::TextEditItem;
use utils::{get::Get, text_edit::TextEditItem};

use super::{
CompletionItem, CompletionItemKind, expr,
Expand Down
19 changes: 9 additions & 10 deletions crates/ide/src/completion/engine/port_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,12 @@ fn complete_ansi_port_list(
})
.collect::<Vec<_>>();

items.extend(keywords
.iter()
.filter(|kw| kw.starts_with(prefix))
.map(|kw| CompletionItem {
label: (*kw).to_string(),
kind: CompletionItemKind::Keyword,
edit: Some(TextEditItem::replace(ctx.replacement, (*kw).to_string())),
snippet_edit: None,
}));
items.extend(keywords.iter().filter(|kw| kw.starts_with(prefix)).map(|kw| CompletionItem {
label: (*kw).to_string(),
kind: CompletionItemKind::Keyword,
edit: Some(TextEditItem::replace(ctx.replacement, (*kw).to_string())),
snippet_edit: None,
}));

items
}
Expand Down Expand Up @@ -84,7 +81,9 @@ fn visible_typedefs_in_module_header(db: &RootDb, position: FilePosition) -> Vec
names.extend(
db.module_scope(module_id)
.iter()
.filter_map(|(ident, entry)| matches!(entry, ModuleEntry::TypedefId(_)).then_some(ident))
.filter_map(|(ident, entry)| {
matches!(entry, ModuleEntry::TypedefId(_)).then_some(ident)
})
.map(|ident| ident.to_string()),
);

Expand Down
9 changes: 7 additions & 2 deletions crates/ide/src/completion/engine/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ use utils::{lines::LineEnding, text_edit::TextSize};
use vfs::{ChangeKind, ChangedFile, FileId, FileSet, VfsPath};

use super::*;
use crate::{analysis_host::AnalysisHost, completion::context::TriggerChar};
use crate::{
analysis_host::AnalysisHost, completion::context::TriggerChar,
test_utils::normalize_fixture_text,
};

fn setup(text: &str) -> (AnalysisHost, FilePosition) {
let text = normalize_fixture_text(text);
let marker = "/*caret*/";
let off = text.find(marker).expect("missing /*caret*/");
let mut owned = text.to_string();
let mut owned = text;
owned = owned.replace(marker, "");

let file_id = FileId(0);
Expand Down Expand Up @@ -64,6 +68,7 @@ fn parse_trigger(line: &str) -> Option<TriggerChar> {

fn load_fixture(path: &PathBuf) -> (String, Option<TriggerChar>) {
let text = std::fs::read_to_string(path).unwrap_or_else(|err| panic!("read {path:?}: {err}"));
let text = normalize_fixture_text(&text);
let mut lines = text.lines();
let Some(first) = lines.next() else {
return (text, None);
Expand Down
22 changes: 8 additions & 14 deletions crates/ide/src/completion/engine/typed_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ fn packed_bit_width(db: &RootDb, module: &hir::hir_def::module::Module, ty: Data
let dim = dim?;
let width = match dim {
Dimension::Range(left, right) => {
let l = eval_const_i128(module, left, db)?;
let r = eval_const_i128(module, right, db)?;
let l = eval_const_i128(module, left)?;
let r = eval_const_i128(module, right)?;
i128::abs(l - r).checked_add(1)?
}
Dimension::Size(size) => eval_const_i128(module, size, db)?,
Dimension::Size(size) => eval_const_i128(module, size)?,
};
let width: u64 = width.try_into().ok()?;
product = product.checked_mul(width)?;
Expand All @@ -252,24 +252,20 @@ fn int_kind_width(kind: IntKind) -> usize {
}
}

fn eval_const_i128(
module: &hir::hir_def::module::Module,
expr_id: ExprId,
db: &RootDb,
) -> Option<i128> {
fn eval_const_i128(module: &hir::hir_def::module::Module, expr_id: ExprId) -> Option<i128> {
match module.get(expr_id) {
Expr::Literal(Literal::Int(int)) => int.get_single_word().map(|v| v as i128),
Expr::Unary { op, expr } => {
let v = eval_const_i128(module, *expr, db)?;
let v = eval_const_i128(module, *expr)?;
match op {
UnaryOp::Pos => Some(v),
UnaryOp::Neg => Some(v.checked_neg()?),
_ => None,
}
}
Expr::Binary { op, lhs, rhs } => {
let l = eval_const_i128(module, *lhs, db)?;
let r = eval_const_i128(module, *rhs, db)?;
let l = eval_const_i128(module, *lhs)?;
let r = eval_const_i128(module, *rhs)?;
match op {
BinaryOp::Add => l.checked_add(r),
BinaryOp::Sub => l.checked_sub(r),
Expand All @@ -281,9 +277,7 @@ fn eval_const_i128(
_ => None,
}
}
Expr::Cast { expr, .. } | Expr::SignedCast { expr, .. } => {
eval_const_i128(module, *expr, db)
}
Expr::Cast { expr, .. } | Expr::SignedCast { expr, .. } => eval_const_i128(module, *expr),
_ => None,
}
}
Loading
Loading