Skip to content

Commit 7c9d3ba

Browse files
kinto0meta-codesync[bot]
authored andcommitted
range without decorators
Summary: in screenshot 1 you see that the range includes decorators which isn't great. this diff takes those off of classes/functions Reviewed By: stroxler Differential Revision: D85865653 fbshipit-source-id: 0efa95e68339d2fcdb1c403624962f1e63752dfe
1 parent 250bc89 commit 7c9d3ba

File tree

2 files changed

+91
-2
lines changed

2 files changed

+91
-2
lines changed

pyrefly/lib/state/state.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,6 +1633,19 @@ fn collect_folding_ranges(body: &[Stmt]) -> Vec<(TextRange, Option<FoldingRangeK
16331633
use ruff_python_ast::ExceptHandler;
16341634
use ruff_text_size::Ranged;
16351635

1636+
fn range_without_decorators(
1637+
range: TextRange,
1638+
decorators: &[ruff_python_ast::Decorator],
1639+
) -> TextRange {
1640+
let decorators_range = decorators
1641+
.first()
1642+
.map(|first| first.range().cover(decorators.last().unwrap().range()));
1643+
1644+
decorators_range.map_or(range, |x| {
1645+
range.add_start(x.len() + ruff_text_size::TextSize::from(1))
1646+
})
1647+
}
1648+
16361649
struct FoldingRangeCollector {
16371650
ranges: Vec<(TextRange, Option<FoldingRangeKind>)>,
16381651
}
@@ -1649,12 +1662,14 @@ fn collect_folding_ranges(body: &[Stmt]) -> Vec<(TextRange, Option<FoldingRangeK
16491662
match stmt {
16501663
Stmt::FunctionDef(func) => {
16511664
if !func.body.is_empty() {
1652-
self.ranges.push((func.range, None));
1665+
let range = range_without_decorators(func.range, &func.decorator_list);
1666+
self.ranges.push((range, None));
16531667
}
16541668
}
16551669
Stmt::ClassDef(class) => {
16561670
if !class.body.is_empty() {
1657-
self.ranges.push((class.range, None));
1671+
let range = range_without_decorators(class.range, &class.decorator_list);
1672+
self.ranges.push((range, None));
16581673
}
16591674
}
16601675
Stmt::If(if_stmt) => {

pyrefly/lib/test/lsp/folding_ranges.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,3 +478,77 @@ if True:
478478
report.trim(),
479479
);
480480
}
481+
482+
#[test]
483+
fn folding_ranges_with_decorators() {
484+
let code = r#"
485+
from typing import overload, Any
486+
487+
@overload
488+
def foo(x: int) -> str: ...
489+
@overload
490+
def foo(x: str) -> int: ...
491+
def foo(*args, **kwargs) -> Any:
492+
pass
493+
494+
def decorator1(cls):
495+
return cls
496+
497+
@decorator1
498+
class MyClass:
499+
"""Class docstring"""
500+
501+
@staticmethod
502+
def static_method():
503+
pass
504+
505+
@classmethod
506+
def class_method(cls):
507+
pass
508+
"#;
509+
510+
let report =
511+
get_batched_lsp_operations_report_no_cursor(&[("main", code)], get_folding_ranges_report);
512+
513+
assert_eq!(
514+
r#"# main.py
515+
516+
[
517+
{
518+
"start_line": 4,
519+
"end_line": 4
520+
},
521+
{
522+
"start_line": 6,
523+
"end_line": 6
524+
},
525+
{
526+
"start_line": 7,
527+
"end_line": 8
528+
},
529+
{
530+
"start_line": 10,
531+
"end_line": 11
532+
},
533+
{
534+
"start_line": 14,
535+
"end_line": 23
536+
},
537+
{
538+
"start_line": 15,
539+
"end_line": 15,
540+
"kind": "comment"
541+
},
542+
{
543+
"start_line": 18,
544+
"end_line": 19
545+
},
546+
{
547+
"start_line": 22,
548+
"end_line": 23
549+
}
550+
]"#
551+
.trim(),
552+
report.trim(),
553+
);
554+
}

0 commit comments

Comments
 (0)