Skip to content

Commit

Permalink
Get variable list from/to_proto working
Browse files Browse the repository at this point in the history
Note: For some reason variable entries aren't rendering even though
everything is being sent
  • Loading branch information
Anthony-Eid committed Dec 9, 2024
1 parent c95993c commit 2479d76
Show file tree
Hide file tree
Showing 3 changed files with 312 additions and 13 deletions.
206 changes: 203 additions & 3 deletions crates/dap/src/proto_conversions.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use client::proto::DapScope;
use client::proto::{
DapChecksum, DapChecksumAlgorithm, DapScope, DapScopePresentationHint, DapSource,
DapSourcePresentationHint, DapStackPresentationHint, DapVariable,
};

pub trait ProtoConversion {
type DapType;
Expand All @@ -7,6 +10,24 @@ pub trait ProtoConversion {
fn from_proto(payload: Self::DapType) -> Self;
}

impl<T> ProtoConversion for Vec<T>
where
T: ProtoConversion,
{
type DapType = Vec<T::DapType>;

fn to_proto(&self) -> Self::DapType {
self.iter().map(|item| item.to_proto()).collect()
}

fn from_proto(payload: Self::DapType) -> Self {
payload
.into_iter()
.map(|item| T::from_proto(item))
.collect()
}
}

impl ProtoConversion for dap_types::Scope {
type DapType = DapScope;

Expand All @@ -26,7 +47,186 @@ impl ProtoConversion for dap_types::Scope {
}
}

fn from_proto(_payload: Self::DapType) -> Self {
todo!()
fn from_proto(payload: Self::DapType) -> Self {
Self {
name: payload.name,
presentation_hint: DapScopePresentationHint::from_i32(payload.presentation_hint)
.map(|val| dap_types::ScopePresentationHint::from_proto(val)),
variables_reference: payload.variables_reference,
named_variables: payload.named_variables,
indexed_variables: payload.indexed_variables,
expensive: payload.expensive,
source: payload.source.map(|src| dap_types::Source::from_proto(src)),
line: payload.line,
end_line: payload.end_line,
column: payload.column,
end_column: payload.end_column,
}
}
}

impl ProtoConversion for dap_types::Variable {
type DapType = DapVariable;

fn to_proto(&self) -> Self::DapType {
Self::DapType {
name: self.name.clone(),
value: self.value.clone(),
r#type: self.type_.clone(),
evaluate_name: self.evaluate_name.clone(),
variables_reference: self.variables_reference,
named_variables: self.named_variables,
indexed_variables: self.indexed_variables,
memory_reference: self.memory_reference.clone(),
}
}

fn from_proto(payload: Self::DapType) -> Self {
Self {
name: payload.name,
value: payload.value,
type_: payload.r#type,
evaluate_name: payload.evaluate_name,
presentation_hint: None, // TODO Debugger Collab Add this
variables_reference: payload.variables_reference,
named_variables: payload.named_variables,
indexed_variables: payload.indexed_variables,
memory_reference: payload.memory_reference,
}
}
}

impl ProtoConversion for dap_types::ScopePresentationHint {
type DapType = DapScopePresentationHint;

fn to_proto(&self) -> Self::DapType {
match self {
dap_types::ScopePresentationHint::Locals => DapScopePresentationHint::Locals,
dap_types::ScopePresentationHint::Arguments => DapScopePresentationHint::Arguments,
dap_types::ScopePresentationHint::Registers => DapScopePresentationHint::Registers,
dap_types::ScopePresentationHint::ReturnValue => DapScopePresentationHint::ReturnValue,
dap_types::ScopePresentationHint::Unknown => DapScopePresentationHint::ScopeUnknown,
&_ => unreachable!(),
}
}

fn from_proto(payload: Self::DapType) -> Self {
match payload {
DapScopePresentationHint::Locals => dap_types::ScopePresentationHint::Locals,
DapScopePresentationHint::Arguments => dap_types::ScopePresentationHint::Arguments,
DapScopePresentationHint::Registers => dap_types::ScopePresentationHint::Registers,
DapScopePresentationHint::ReturnValue => dap_types::ScopePresentationHint::ReturnValue,
DapScopePresentationHint::ScopeUnknown => dap_types::ScopePresentationHint::Unknown,
}
}
}

impl ProtoConversion for dap_types::SourcePresentationHint {
type DapType = DapSourcePresentationHint;

fn to_proto(&self) -> Self::DapType {
match self {
dap_types::SourcePresentationHint::Normal => DapSourcePresentationHint::SourceNormal,
dap_types::SourcePresentationHint::Emphasize => DapSourcePresentationHint::Emphasize,
dap_types::SourcePresentationHint::Deemphasize => {
DapSourcePresentationHint::Deemphasize
}
dap_types::SourcePresentationHint::Unknown => DapSourcePresentationHint::SourceUnknown,
&_ => unreachable!(),
}
}

fn from_proto(payload: Self::DapType) -> Self {
match payload {
DapSourcePresentationHint::SourceNormal => dap_types::SourcePresentationHint::Normal,
DapSourcePresentationHint::Emphasize => dap_types::SourcePresentationHint::Emphasize,
DapSourcePresentationHint::Deemphasize => {
dap_types::SourcePresentationHint::Deemphasize
}
DapSourcePresentationHint::SourceUnknown => dap_types::SourcePresentationHint::Unknown,
}
}
}

impl ProtoConversion for dap_types::Checksum {
type DapType = DapChecksum;

fn to_proto(&self) -> Self::DapType {
DapChecksum {
algorithm: self.algorithm.to_proto().into(),
checksum: self.checksum.clone(),
}
}

fn from_proto(payload: Self::DapType) -> Self {
Self {
algorithm: dap_types::ChecksumAlgorithm::from_proto(payload.algorithm()),
checksum: payload.checksum,
}
}
}

impl ProtoConversion for dap_types::ChecksumAlgorithm {
type DapType = DapChecksumAlgorithm;

fn to_proto(&self) -> Self::DapType {
match self {
dap_types::ChecksumAlgorithm::Md5 => DapChecksumAlgorithm::Md5,
dap_types::ChecksumAlgorithm::Sha1 => DapChecksumAlgorithm::Sha1,
dap_types::ChecksumAlgorithm::Sha256 => DapChecksumAlgorithm::Sha256,
dap_types::ChecksumAlgorithm::Timestamp => DapChecksumAlgorithm::Timestamp,
_ => unreachable!(),
}
}

fn from_proto(payload: Self::DapType) -> Self {
match payload {
DapChecksumAlgorithm::Md5 => dap_types::ChecksumAlgorithm::Md5,
DapChecksumAlgorithm::Sha1 => dap_types::ChecksumAlgorithm::Sha1,
DapChecksumAlgorithm::Sha256 => dap_types::ChecksumAlgorithm::Sha256,
DapChecksumAlgorithm::Timestamp => dap_types::ChecksumAlgorithm::Timestamp,
DapChecksumAlgorithm::ChecksumAlgorithmUnspecified => unreachable!(),
}
}
}

impl ProtoConversion for dap_types::Source {
type DapType = DapSource;

fn to_proto(&self) -> Self::DapType {
Self::DapType {
name: self.name.clone(),
path: self.path.clone(),
source_reference: self.source_reference,
presentation_hint: self.presentation_hint.map(|hint| hint.to_proto().into()),
origin: self.origin.clone(),
sources: self
.sources
.clone()
.map(|src| src.to_proto())
.unwrap_or_default(),
adapter_data: Default::default(), // TODO: Need adapter_data field
checksums: self
.checksums
.clone()
.map(|c| c.to_proto())
.unwrap_or_default(),
}
}

fn from_proto(payload: Self::DapType) -> Self {
Self {
name: payload.name.clone(),
path: payload.path.clone(),
source_reference: payload.source_reference,
presentation_hint: payload
.presentation_hint
.and_then(|val| DapSourcePresentationHint::from_i32(val))
.map(|val| dap_types::SourcePresentationHint::from_proto(val)),
origin: payload.origin.clone(),
sources: Some(Vec::from_proto(payload.sources)),
checksums: Some(Vec::from_proto(payload.checksums)),
adapter_data: None,
}
}
}
117 changes: 108 additions & 9 deletions crates/debugger_ui/src/variable_list.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::stack_frame_list::{StackFrameList, StackFrameListEvent};
use anyhow::Result;
use dap::{
client::DebugAdapterClientId,
proto_conversions::{self, ProtoConversion},
Scope, ScopePresentationHint, Variable,
client::DebugAdapterClientId, proto_conversions::ProtoConversion, Scope, ScopePresentationHint,
Variable,
};
use editor::{
actions::{self, SelectAll},
Expand All @@ -16,7 +15,8 @@ use gpui::{
};
use menu::Confirm;
use project::dap_store::DapStore;
use rpc::proto::{self, SetDebuggerPanelItem};
use proto::debugger_variable_list_entry::Entry;
use rpc::proto::{self, VariableListEntries, VariableListScopes};
use std::{
collections::{BTreeMap, HashMap, HashSet},
sync::Arc,
Expand Down Expand Up @@ -143,6 +143,52 @@ pub enum VariableListEntry {
},
}

impl VariableListEntry {
pub(crate) fn to_proto(&self) -> proto::DebuggerVariableListEntry {
let entry = match &self {
VariableListEntry::Scope(scope) => Entry::Scope(scope.to_proto()),
VariableListEntry::Variable {
depth,
scope,
variable,
has_children,
container_reference,
} => Entry::Variable(proto::VariableListEntryVariable {
depth: *depth as u64,
scope: Some(scope.to_proto()),
variable: Some(variable.to_proto()),
has_children: *has_children,
container_reference: *container_reference,
}),
VariableListEntry::SetVariableEditor { depth, state } => {
Entry::SetVariableEditor(proto::VariableListEntrySetState {
depth: *depth as u64,
state: Some(state.to_proto()),
})
}
};

proto::DebuggerVariableListEntry { entry: Some(entry) }
}

pub(crate) fn from_proto(entry: proto::DebuggerVariableListEntry) -> Option<Self> {
match entry.entry? {
Entry::Scope(scope) => Some(Self::Scope(Scope::from_proto(scope))),
Entry::Variable(var) => Some(Self::Variable {
depth: var.depth as usize,
scope: Arc::new(Scope::from_proto(var.scope?)),
variable: Arc::new(Variable::from_proto(var.variable?)),
has_children: var.has_children,
container_reference: var.container_reference,
}),
Entry::SetVariableEditor(set_state) => Some(Self::SetVariableEditor {
depth: set_state.depth as usize,
state: SetVariableState::from_proto(set_state.state?)?,
}),
}
}
}

#[derive(Debug)]
struct ScopeVariableIndex {
fetched_ids: HashSet<u64>,
Expand Down Expand Up @@ -266,11 +312,33 @@ impl VariableList {
.as_ref()
.map(SetVariableState::to_proto);

let entries = self
.entries
.iter()
.map(|(key, entries)| VariableListEntries {
stack_frame_id: *key,
entries: entries
.clone()
.iter()
.map(|entry| entry.to_proto())
.collect(),
})
.collect();

let scopes = self
.scopes
.iter()
.map(|(key, scopes)| VariableListScopes {
stack_frame_id: *key,
scopes: scopes.to_proto(),
})
.collect();

proto::DebuggerVariableList {
open_entries,
scopes: Default::default(),
scopes,
set_variable_state,
entries: Default::default(),
entries,
}
}

Expand All @@ -290,9 +358,40 @@ impl VariableList {
.clone()
.and_then(SetVariableState::from_proto);

dbg!("Setting from proto");
dbg!(&self.open_entries);
dbg!(&state.entries);
self.entries = state
.entries
.iter()
.map(|entry| {
(
entry.stack_frame_id,
entry
.entries
.clone()
.iter()
.filter_map(|ele| VariableListEntry::from_proto(ele.clone()))
.collect(),
)
})
.collect();

self.scopes = state
.scopes
.iter()
.map(|scope| {
(
scope.stack_frame_id,
scope
.scopes
.clone()
.iter()
.map(|ele| Scope::from_proto(ele.clone()))
.collect(),
)
})
.collect();

self.build_entries(true, true, cx);

cx.notify();
}

Expand Down
2 changes: 1 addition & 1 deletion crates/proto/proto/zed.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2521,7 +2521,7 @@ enum DebuggerThreadStatus {

message VariableListScopes {
uint64 stack_frame_id = 1;
DapScope scopes = 2;
repeated DapScope scopes = 2;
}

message VariableListEntries {
Expand Down

0 comments on commit 2479d76

Please sign in to comment.