Skip to content

Commit 888113b

Browse files
authored
Extended properties (#25)
* Enabled extended properties * Support extended properties * Reuse function * TODO: multibyte variables not being tracked
1 parent 02abfab commit 888113b

File tree

6 files changed

+148
-29
lines changed

6 files changed

+148
-29
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
CHANGELOG
22
=========
33

4+
main
5+
----
6+
7+
- Show value of variables on current line
8+
- Support `extended_properties` #5
9+
10+
411
0.0.2
512
-----
613

php/test.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
$arra😸ay = [
4+
'int' => 123,
5+
'float' => 123.4,
6+
'string' => "string",
7+
'bool' => true,
8+
'more' => [
9+
'int' => 123,
10+
'float' => 123.4,
11+
'string' => "string",
12+
'bool' => true,
13+
],
14+
];
15+
$a = 2;
16+
$foo = $a;
17+
$foo = $arra😸ay;
18+
19+
$bar = $foo;
20+
21+
22+
(new Foo(true, "foo"))->method3();
23+
call_function("hello");
24+
25+
26+
27+
function call_function(string $hello) {
28+
$var = 123;
29+
$obj = new Foo(false, 'good day');
30+
another_function($hello);
31+
another_function($hello);
32+
another_function($hello);
33+
}
34+
35+
function another_function(string $goodbye) {
36+
echo $goodbye;
37+
38+
39+
foreach (['one', 'two', 'three', 'four'] as $number) {
40+
if ($number === 'one') {
41+
echo "number";
42+
}
43+
echo $number;
44+
}
45+
}
46+
47+
class Foo {
48+
public function __construct(public bool $true, public string $bar) {}
49+
public function method1() {
50+
}
51+
public function method2() {
52+
}
53+
public function method3() {
54+
}
55+
}
56+

src/analyzer.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,5 +166,22 @@ list($var1, $var2) = some_call();
166166
}, line.get(&5).unwrap());
167167
Ok(())
168168
}
169+
170+
#[test]
171+
fn test_cats() -> Result<(), anyhow::Error> {
172+
let source = r#"<?php
173+
$fo😸cat = "12";
174+
"#;
175+
let analysis = Analyser::new().analyze(source)?;
176+
let line = analysis.row(1);
177+
assert_eq!(1, line.values().len());
178+
179+
assert_eq!(&VariableRef{
180+
range: Range::new(Position::new(1,0), Position::new(1,10)),
181+
name: "$fo😸cat".to_string(),
182+
value: None,
183+
}, line.get(&0).unwrap());
184+
Ok(())
185+
}
169186
}
170187

src/app.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,10 @@ impl App {
249249
terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
250250
event: AppEvent,
251251
) -> Result<()> {
252-
info!("Handling event {:?}", event);
252+
match event {
253+
AppEvent::Tick => (),
254+
_ => info!("Handling event {:?}", event),
255+
};
253256
match event {
254257
AppEvent::Tick => (),
255258
AppEvent::Quit => self.quit = true,
@@ -296,10 +299,13 @@ impl App {
296299
AppEvent::ClientConnected(s) => {
297300
let mut client = self.client.lock().await;
298301
let response = client.deref_mut().connect(s).await?;
299-
client.feature_set(
300-
"max_depth",
301-
self.context_depth.to_string().as_str()
302-
).await?;
302+
for (feature, value) in [
303+
("max_depth",self.context_depth.to_string().as_str()),
304+
("extended_properties","1"),
305+
] {
306+
info!("setting feature {} to {:?}", feature, value);
307+
client.feature_set(feature, value).await?;
308+
}
303309
self.is_connected = true;
304310
self.server_status = None;
305311
self.view_current = CurrentView::Session;

src/dbgp/client.rs

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ impl DbgpClient {
187187
if xml.is_empty() {
188188
return Err(anyhow::anyhow!("Empty XML response"));
189189
}
190-
debug!("[dbgp] << {}", xml);
191190
parse_xml(xml.as_str())
192191
}
193192

@@ -390,17 +389,24 @@ fn parse_context_get(element: &mut Element) -> Result<ContextGetResponse, anyhow
390389
while let Some(mut child) = element.take_child("property") {
391390
let encoding = child.attributes.get("encoding").map(|s| s.to_string());
392391
let p = Property {
393-
name: child
392+
name: match child
394393
.attributes
395-
.get("name")
396-
.expect("Expected name to be set")
397-
.to_string(),
398-
fullname: child
394+
.get("name") {
395+
Some(name) => name.to_string(),
396+
None => decode_element(child.get_child("name")).unwrap_or("".to_string())
397+
},
398+
fullname: match child
399399
.attributes
400-
.get("name")
401-
.expect("Expected fullname to be set")
402-
.to_string(),
403-
classname: child.attributes.get("classname").map(|s| s.to_string()),
400+
.get("fullname") {
401+
Some(name) => name.to_string(),
402+
None => decode_element(child.get_child("fullname")).unwrap_or("".to_string())
403+
},
404+
classname: match child
405+
.attributes
406+
.get("classname") {
407+
Some(name) => Some(name.to_string()),
408+
None => decode_element(child.get_child("classname"))
409+
},
404410
page: child
405411
.attributes
406412
.get("page")
@@ -424,23 +430,33 @@ fn parse_context_get(element: &mut Element) -> Result<ContextGetResponse, anyhow
424430
address: child.attributes.get("address").map(|name| name.to_string()),
425431
encoding: encoding.clone(),
426432
children: parse_context_get(&mut child).unwrap().properties,
427-
value: match child.children.first() {
428-
Some(XMLNode::CData(cdata)) => Some(match encoding {
433+
value: decode_element(Some(&child)),
434+
};
435+
properties.push(p);
436+
}
437+
Ok(ContextGetResponse { properties })
438+
}
439+
440+
fn decode_element(element: Option<&Element>) -> Option<String> {
441+
match element {
442+
Some(e) => {
443+
let encoding = e.attributes.get("encoding");
444+
match e.children.first() {
445+
Some(XMLNode::CData(cdata)) => match encoding {
429446
Some(encoding) => match encoding.as_str() {
430447
"base64" => {
431-
String::from_utf8(general_purpose::STANDARD.decode(cdata).unwrap())
432-
.unwrap()
448+
Some(String::from_utf8(general_purpose::STANDARD.decode(cdata).unwrap())
449+
.unwrap())
433450
}
434-
_ => cdata.to_string(),
451+
_ => Some(cdata.to_string()),
435452
},
436-
_ => cdata.to_string(),
437-
}),
453+
_ => Some(cdata.to_string()),
454+
},
438455
_ => None,
439-
},
440-
};
441-
properties.push(p);
456+
}
457+
}
458+
None => None,
442459
}
443-
Ok(ContextGetResponse { properties })
444460
}
445461

446462
fn parse_stack_get(element: &Element) -> StackGetResponse {
@@ -594,6 +610,7 @@ function call_function(string $hello) {
594610
<property name="bar" fullname="$this-&gt;bar" facet="public" type="string" size="3" encoding="base64"><![CDATA[Zm9v]]></property>
595611
<property name="handle" fullname="$this-&gt;handle" facet="private" type="resource"><![CDATA[resource id='18' type='stream']]></property>
596612
</property>
613+
<property type="array"><name encoding="base64"><![CDATA[JGFycvCfmLhheQ==]]></name><fullname encoding="base64"><![CDATA[JGFycvCfmLhheQ==]]></fullname></property>
597614
</response>"#,
598615
)?;
599616

@@ -675,7 +692,7 @@ function call_function(string $hello) {
675692
children: vec![
676693
Property {
677694
name: "true".to_string(),
678-
fullname: "true".to_string(),
695+
fullname: "$this->true".to_string(),
679696
classname: None,
680697
page: None,
681698
pagesize: None,
@@ -690,7 +707,7 @@ function call_function(string $hello) {
690707
},
691708
Property {
692709
name: "bar".to_string(),
693-
fullname: "bar".to_string(),
710+
fullname: "$this->bar".to_string(),
694711
classname: None,
695712
page: None,
696713
pagesize: None,
@@ -705,7 +722,7 @@ function call_function(string $hello) {
705722
},
706723
Property {
707724
name: "handle".to_string(),
708-
fullname: "handle".to_string(),
725+
fullname: "$this->handle".to_string(),
709726
classname: None,
710727
page: None,
711728
pagesize: None,
@@ -724,6 +741,21 @@ function call_function(string $hello) {
724741
encoding: None,
725742
value: None,
726743
},
744+
Property {
745+
name: "$arr😸ay".to_string(),
746+
fullname: "$arr😸ay".to_string(),
747+
classname: None,
748+
page: None,
749+
pagesize: None,
750+
property_type: PropertyType::Array,
751+
facet: None,
752+
size: None,
753+
children: vec![],
754+
key: None,
755+
address: None,
756+
encoding: None,
757+
value: None,
758+
},
727759
],
728760
};
729761
assert_eq!(expected, response)

src/view/source.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::app::App;
33
use crate::dbgp::client::Property;
44
use crate::dbgp::client::PropertyType;
55
use crate::event::input::AppEvent;
6+
use log::info;
67
use ratatui::layout::Constraint;
78
use ratatui::layout::Layout;
89
use ratatui::layout::Position;

0 commit comments

Comments
 (0)