Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
bf0ce39
Report ambiguous overrides
JonatanWaern Dec 1, 2025
404524e
Refactor ReferenceMatches
JonatanWaern Jan 14, 2026
5253e8c
Change debug level of some prints
JonatanWaern Jan 16, 2026
f390449
Rework symbol methodology for methods
JonatanWaern Jan 12, 2026
3b12882
Rework how fp-based symbol lookup works
JonatanWaern Jan 16, 2026
5062809
Rework how abstract methods and template methods work
JonatanWaern Jan 16, 2026
7b05d2e
Clarify and ensure behavior of goto- operations
JonatanWaern Jan 19, 2026
02854b1
Refactor and move semantic lookup methods
JonatanWaern Jan 21, 2026
b57226c
Fixes to method lookups
JonatanWaern Jan 23, 2026
6caaee1
Allow references to carry extra information
JonatanWaern Jan 23, 2026
ccda8df
Fix goto-implementations on templates
JonatanWaern Jan 23, 2026
299af7e
Fix goto-definition on abstract methods
JonatanWaern Jan 26, 2026
56abac0
Fix a debug print
JonatanWaern Jan 26, 2026
b177c70
Fix symbol binding around indirect method overrides
JonatanWaern Jan 26, 2026
cf7c5e2
Fix inconsistencies in lookups
JonatanWaern Jan 27, 2026
1caa5bc
Add explicit method decl provisional
JonatanWaern Jan 28, 2026
6f94496
Correctly report missing templates in in-each
JonatanWaern Jan 28, 2026
9499c09
Allow reference-in-method to fall through default calls
JonatanWaern Jan 29, 2026
1775ebf
Only bind implementations between methods within the same object
JonatanWaern Feb 2, 2026
8ad5bae
Bind implementations on object symbols to in-eachs that apply to them
JonatanWaern Feb 2, 2026
d7b90c8
Fix bug in goto-decl on parameters
JonatanWaern Feb 5, 2026
06cfbb8
Do not return abstract method declaration in goto-impl
JonatanWaern Feb 9, 2026
9807b12
Use .identity() to index defined_methods consistently
JonatanWaern Feb 9, 2026
57c256f
Optimize lookup_symbols slightly
JonatanWaern Feb 9, 2026
6006479
Remove redundant symbol iteration
JonatanWaern Feb 9, 2026
431fa2e
Typo fixes
JonatanWaern Feb 9, 2026
c727b0e
Fix bug in get_bases
JonatanWaern Feb 16, 2026
008c675
Allow late-shared default calls
JonatanWaern Feb 9, 2026
c2b9daa
Don't panic on declaration-only methods
JonatanWaern Feb 18, 2026
8d33292
Do not warn about double-generating methods
JonatanWaern Feb 20, 2026
2678f2c
Verify and preserve implementation variant on abstract methods
JonatanWaern Feb 23, 2026
c23db70
Slightly improve missing template message
JonatanWaern Feb 23, 2026
f844280
Remove unnecessary import
JonatanWaern Feb 23, 2026
3606d50
Remove unused function
JonatanWaern Feb 23, 2026
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
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@
or footers
- The DLS will no longer fail to parse files with unicode characters in cblock
header or footers, or in multiline comments
- The DLS will now report when an ambiguous default call is made
- Improvements and clarifications to connections between symbols and references,
for details, see [USAGE.md](USAGE.md).
-- Method declared in unrelated templates in an allowed way will now have their
references correctly resolved.
-- Goto-reference on default calls will now go to the methods that may be called.
-- Goto-implementations on templates will now go to all places where they are
instantiated.
-- Goto-implementations on objects will now go to all the 'in each' declarations
which apply to that object.
- Added parser support for provisional 'explicit\_method\_decls'
- The DLS will now correctly report missing template names in 'in each' constructs

## 0.9.17
- Fixed linter wrongly throwing an error on space after `defined` keyword
Expand All @@ -21,7 +33,7 @@

## 0.9.15
- Added support for line length and breaking rules regarding line-breaks after opening parentheses, method output arguments, conditional expressions and binary operands.
- Added support for indendation rule indent_continuation_line.
- Added support for indendation rule indent\_continuation\_line.
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling: indendation should be indentation.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Willfix in different PR

- Optimizations in how the server resolves file paths, should reduce
time-to-ready for the server when first starting by about 50%, depending
on the complexity of the include tree.
Expand Down
72 changes: 72 additions & 0 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,78 @@ details consult the documentation of the client.
As this file is currently a work in progress, relevant details may be
missing or incomplete.

## Clarification of semantics of Symbol Lookups
DML is at its core a _declarative_ language centered around a Device,
and declarations are merged together according to the hierarchical
structure. Thus, the meaning of `goto-definition`, `goto-declaration`,
`goto-implementations`, and `goto-references` may not be similar to how
they behave in other languages.
Here is a clarification of what each operation means for each object
kind in DML. It is worth noting that unless otherwise specified, a goto-
operation on a reference is equivalent to the same operation on each symbol
that it could refer to.

*NOTE:* Due to limitations in the DLS, a matching from references to
declarations is not always possible. `goto-references` may provide incomplete
info and `goto-definition` and similar on a reference may fail in some cases.
See issues [#13](https://github.com/intel/dml-language-server/issues/13),
[#23](https://github.com/intel/dml-language-server/issues/23),
[#26](https://github.com/intel/dml-language-server/issues/26),
[#30](https://github.com/intel/dml-language-server/issues/30), and
[#65](https://github.com/intel/dml-language-server/issues/65).

### On Composite Objects (banks, registers, implements, etc.)
`goto-declaration` and `goto-definition` on a composite object are equivalent.
They will find the locations of all object declarations that may be
merged with the one at the name.

`goto-implementations` on objects will find all `in each` declaration block that
applies to that object.

`goto-references` will go to any location where the symbol is referred to
directly.

### On Methods
`goto-declaration` on a method will find the most-overridden declaration
or definition of the method, this will usually be a 'default' or
abstract declaration.

`goto-definition` on a method reference will find all definitions of that method
that could be called from that reference, or the declaration of the method if it
has no non-abstract definitions. Note that this will NOT point to
method declarations that are entirely overridden. `goto-definition` on a method
name will go to the nearest definition of the method. For non-abstract methods
this is a no-op.

`goto-implementations` on a method will find all method declarations that
could override it.

`goto-references` will go to any location where the method is referred to
directly (including call sites).

### On Parameters
`goto-declaration` on a parameter will find the most-overridden declaration of
this parameter, usually a 'default' or abstract declaration.

`goto-definition` on a parameter will find all definitions that are used within
a method.

`goto-implementations` on a parameter is currently unused.

`goto-references` will go to any location where the parameter is referred to
directly.

### On Templates
`goto-declaration` and `goto-definition` are equivalent, and will both give the
template declaration site.

`goto-implementations` will give each location where the template is directly
instantiated.

`goto-references` will go to any location where the template is referred to,
including direct instantiation sites (so this is a super-set of
`goto-implementations`)

## In-Line Linting Configuration
It may be desireable to control linting on a per-file basis, rather than
relying on the linting configuration. This can be done with in-line
Expand Down
12 changes: 6 additions & 6 deletions src/actions/analysis_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ impl AnalysisQueue {
|| !device_lock.is_empty()
|| !isolated_lock.is_empty();
if has_work {
debug!("Queue still has work ({:?}, {:?}, {:?})",
trace!("Queue still has work ({:?}, {:?}, {:?})",
queue_lock, device_lock, isolated_lock);
}
has_work
Expand Down Expand Up @@ -296,7 +296,7 @@ impl AnalysisQueue {
for job in queue_lock.iter() {
if let QueuedJob::IsolatedAnalysisJob(ijob) = job {
if paths.contains(&ijob.path) {
debug!("Detected there is still isolated \
trace!("Detected there is still isolated \
work in queue on {:?}",
&ijob.path);
return true;
Expand All @@ -308,7 +308,7 @@ impl AnalysisQueue {
let isolated_lock = self.isolated_tracker.lock().unwrap();
for (_, path) in isolated_lock.iter() {
if paths.contains(path) {
debug!("Detected there is still isolated \
trace!("Detected there is still isolated \
work in-flight on {:?}",
path);
return true;
Expand All @@ -326,7 +326,7 @@ impl AnalysisQueue {
for job in queue_lock.iter() {
if let QueuedJob::DeviceAnalysisJob(ijob) = job {
if paths.contains(&ijob.root.path) {
debug!("Detected there is still device \
trace!("Detected there is still device \
work in queue on {:?}",
&ijob.root.path);
return true;
Expand All @@ -338,7 +338,7 @@ impl AnalysisQueue {
let device_lock = self.device_tracker.lock().unwrap();
for (path, _) in device_lock.values() {
if paths.contains(path) {
debug!("Detected there is still device \
trace!("Detected there is still device \
work in-flight on {:?}",
path);
return true;
Expand Down Expand Up @@ -613,7 +613,7 @@ impl LinterJob {
self.file.clone())).ok();
},
Err(e) => {
trace!("Failed to create isolated linter analysis: {}", e);
debug!("Failed to create isolated linter analysis: {}", e);
}
}
}
Expand Down
38 changes: 8 additions & 30 deletions src/actions/analysis_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 and MIT
//! Stores currently completed analysis.

use log::{debug, trace, info};
use log::{debug, info, trace};

use crossbeam::channel;

Expand All @@ -14,13 +14,12 @@ use std::sync::Mutex;
use std::time::{Duration, SystemTime};

use crate::actions::ContextDefinition;
use crate::analysis::scope::{ContextedSymbol, ContextKey};
use crate::analysis::scope::ContextKey;
use crate::analysis::structure::objects::Import;
use crate::analysis::{IsolatedAnalysis, DeviceAnalysis, DMLError};
use crate::analysis::{DMLError, DeviceAnalysis, IsolatedAnalysis};

use crate::lsp_data::*;
use crate::analysis::parsing::tree::{ZeroSpan, ZeroFilePosition};
use crate::analysis::reference::Reference;
use crate::server::ServerToHandle;

use crate::lint::LinterAnalysis;
Expand Down Expand Up @@ -211,27 +210,6 @@ impl AnalysisStorage {
}
}

pub fn context_symbol_at_pos<'t>(&'t self, pos: &ZeroFilePosition) ->
Result<Option<ContextedSymbol<'t>>, AnalysisLookupError> {
let canon_path = CanonPath::from_path_buf(pos.path())
.ok_or(AnalysisLookupError::NoFile)?;
let analysis = self.get_isolated_analysis(&canon_path)?;
let mut context = analysis.lookup_context_symbol(pos);
// Patch out leading 'device' context, unneeded
if let Some(ref mut ic) = context {
ic.remove_head_context();
}
Ok(context)
}

pub fn reference_at_pos(&self, pos: &ZeroFilePosition) ->
Result<Option<&Reference>, AnalysisLookupError> {
let canon_path = CanonPath::from_path_buf(pos.path())
.ok_or(AnalysisLookupError::NoFile)?;
let analysis = self.get_isolated_analysis(&canon_path)?;
Ok(analysis.lookup_reference(pos))
}

pub fn first_context_at_pos(&self, pos: &ZeroFilePosition) ->
Result<Option<ContextKey>, AnalysisLookupError> {
let canon_path = CanonPath::from_path_buf(pos.path())
Expand Down Expand Up @@ -306,7 +284,7 @@ impl AnalysisStorage {
};
contexts.insert(None);

debug!("Full contexts for {:?} are {:?}", path, contexts);
trace!("Full contexts for {:?} are {:?}", path, contexts);

if self.get_isolated_analysis(path).map_or(
false, |a|a.is_device_file()) {
Expand Down Expand Up @@ -489,7 +467,7 @@ impl AnalysisStorage {
pub fn update_analysis(&mut self, resolver: &PathResolver) {
let mut device_analysis = vec![];
let mut results_holder = vec![];
debug!("Updating stored analysises");
trace!("Updating stored analysises");
for r in self.results.try_iter() {
results_holder.push(r);
}
Expand Down Expand Up @@ -566,7 +544,7 @@ impl AnalysisStorage {
|i|!timestamp_is_newer(timestamp,
i.timestamp))
.unwrap_or(false)) {
debug!("was not invalidated by recent \
trace!("was not invalidated by recent \
isolated analysis");
self.device_analysis.insert(canon_path,
TimestampedStorage {
Expand Down Expand Up @@ -628,7 +606,7 @@ impl AnalysisStorage {
fn update_last_use(&self, path: &CanonPath) {
if let Some(mut_lock) = self.last_use.get(path) {
let now = SystemTime::now();
debug!("Updated last-use of {} to {:?}", path.as_str(), now);
trace!("Updated last-use of {} to {:?}", path.as_str(), now);
*mut_lock.lock().unwrap() = now;
}
}
Expand Down Expand Up @@ -677,7 +655,7 @@ impl AnalysisStorage {
if let Some(device_timestamp) = self.device_analysis.get(path)
.map(|device|device.timestamp)
{
debug!("Timestamp is {:?}", device_timestamp);
trace!("Timestamp is {:?}", device_timestamp);
for dependee_path in self.all_dependencies(path, Some(path)) {
// NOTE: This means that calling this function with a missing
// isolated analysis will not tell you the device needs to be
Expand Down
2 changes: 1 addition & 1 deletion src/actions/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ pub fn tooltip<O: Output>(
let hover_span = ctx.convert_pos_to_span(hover_file_path, params.position);
// TODO: sort out how to handle hovers, and what info they should provide
let contents = vec![];
debug!("tooltip: contents.len: {}", contents.len());
trace!("tooltip: contents.len: {}", contents.len());
Ok(Tooltip { contents, range: hover_span.range })
}
11 changes: 6 additions & 5 deletions src/actions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ pub mod notifications;
pub mod requests;
pub mod progress;
pub mod work_pool;
pub mod semantic_lookup;

/// Persistent context shared across all requests and notifications.
pub enum ActionContext<O: Output> {
Expand Down Expand Up @@ -1183,10 +1184,10 @@ impl <O: Output> InitActionContext<O> {
response: sender,
};
if self.check_wait(&wait) {
debug!("Wait {:?} was immediately completed", wait);
trace!("Wait {:?} was immediately completed", wait);
Ok(self.check_wait_satisfied(&wait))
} else {
debug!("Wait {:?} needs to wait", wait);
trace!("Wait {:?} needs to wait", wait);
self.add_state_wait(wait);
loop {
match receiver.recv() {
Expand All @@ -1198,7 +1199,7 @@ impl <O: Output> InitActionContext<O> {
}

fn check_wait(&self, wait: &AnalysisStateWaitDefinition) -> bool {
debug!("Checking wait {:?}", wait);
trace!("Checking wait {:?}", wait);
let mut wait_done = true;
let analysis = self.analysis.lock().unwrap();
let queue = &self.analysis_queue;
Expand Down Expand Up @@ -1258,9 +1259,9 @@ impl <O: Output> InitActionContext<O> {
}

if wait_done {
debug!("{:?} was done", wait);
trace!("{:?} was done", wait);
} else {
debug!("{:?} not done", wait);
trace!("{:?} not done", wait);
}
wait_done
}
Expand Down
Loading
Loading