Skip to content

Commit dcca79a

Browse files
authored
Merge pull request #450 from sims1253/feat/r-code-smell-detectors
Clean, well-structured contribution. The `custom_phases` extension point is a great addition to the generic framework — it means any language plugin can inject detection phases without converting to a full plugin. The smell catalog covers the right R anti-patterns with good severity calibration, and the tree-sitter + regex fallback approach for `library_in_function` is thoughtful. Tests are thorough — 22 test cases covering detection, false positive suppression, comment/string handling, nesting, and graceful error handling. Thanks @sims1253!
2 parents bc333c2 + 7062c09 commit dcca79a

9 files changed

Lines changed: 670 additions & 2 deletions

File tree

desloppify/languages/_framework/generic_support/core.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from typing import Any
1111

1212
from desloppify.engine.policy.zones import ZoneRule
13-
from desloppify.languages._framework.base.types import LangConfig
13+
from desloppify.languages._framework.base.types import DetectorPhase, LangConfig
1414
from .capabilities import (
1515
SHARED_PHASE_LABELS,
1616
capability_report,
@@ -60,6 +60,7 @@ def generic_lang(
6060
external_test_dirs: list[str] | None = None,
6161
test_file_extensions: list[str] | None = None,
6262
frameworks: bool = False,
63+
custom_phases: list[DetectorPhase] | None = None,
6364
) -> LangConfig:
6465
"""Build and register a generic language plugin from tool specs.
6566
@@ -86,6 +87,7 @@ def generic_lang(
8687
entry_patterns=entry_patterns,
8788
external_test_dirs=external_test_dirs,
8889
test_file_extensions=test_file_extensions,
90+
custom_phases=custom_phases,
8991
)
9092

9193
from desloppify.languages import register_generic_lang
@@ -102,6 +104,7 @@ def generic_lang(
102104
has_treesitter=has_treesitter,
103105
extract_fn=extract_fn,
104106
dep_graph_fn=dep_graph_fn,
107+
custom_phases=opts.custom_phases,
105108
)
106109

107110
cfg = LangConfig(

desloppify/languages/_framework/generic_support/registration.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class GenericLangOptions:
4141
entry_patterns: list[str] | None = None
4242
external_test_dirs: list[str] | None = None
4343
test_file_extensions: list[str] | None = None
44+
custom_phases: list[DetectorPhase] | None = None
4445

4546

4647
def _register_generic_tool_specs(tool_specs: list[dict[str, Any]]) -> dict[str, FixerConfig]:
@@ -106,6 +107,7 @@ def _build_generic_phases(
106107
has_treesitter: bool,
107108
extract_fn,
108109
dep_graph_fn,
110+
custom_phases: list[DetectorPhase] | None = None,
109111
) -> list[DetectorPhase]:
110112
from desloppify.languages._framework.base.phase_builders import (
111113
detector_phase_security,
@@ -141,6 +143,9 @@ def _build_generic_phases(
141143
phases.append(_make_coupling_phase(dep_graph_fn))
142144
phases.append(detector_phase_test_coverage())
143145

146+
if custom_phases:
147+
phases.extend(custom_phases)
148+
144149
phases.extend(shared_subjective_duplicates_tail())
145150
return phases
146151

desloppify/languages/r/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
"""R language plugin — Jarl, lintr + tree-sitter."""
1+
"""R language plugin — Jarl, lintr + tree-sitter + R-specific smells."""
22

3+
from desloppify.languages._framework.base.types import DetectorPhase
34
from desloppify.languages._framework.generic_support.core import generic_lang
45
from desloppify.languages._framework.treesitter import R_SPEC
6+
from desloppify.languages.r.phases_smells import phase_smells
57

68
generic_lang(
79
name="r",
@@ -31,6 +33,9 @@
3133
detect_markers=["DESCRIPTION", ".Rproj"],
3234
default_src="R",
3335
treesitter_spec=R_SPEC,
36+
custom_phases=[
37+
DetectorPhase("R code smells", phase_smells),
38+
],
3439
)
3540

3641
__all__ = [
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

0 commit comments

Comments
 (0)