feat: CSS/SCSS/LESS parsing with cross-language STYLES edges and conflict detection#61
feat: CSS/SCSS/LESS parsing with cross-language STYLES edges and conflict detection#61CodeBlackwell wants to merge 2 commits into
Conversation
|
Closing — CSS/SCSS support scope is too broad for the current architecture. Tree-sitter CSS parsing doesn't produce meaningful function/class nodes for the knowledge graph. |
|
CSS/SCSS/LESS parsing with cross-language STYLES edges is not in main — parser.py has no CSS/SCSS/LESS support, no STYLES edge type, and no styles_of/styled_by/conflicts_of query patterns. This is a substantial PR (2135 additions) with well-defined scope. Worth reviving — it would be valuable for frontend-heavy codebases. The two-phase approach (per-file extraction + post-build linking) is architecturally sound. |
…ES edges Adds CSS (.css), SCSS (.scss), LESS (.less/.sass) parsing via tree-sitter. Emits STYLES edges from CSS selectors to the HTML/JSX/Vue components they target. Adds cross-file conflict detection for overlapping CSS selectors. Includes bug fixes found during merge: - Propagate jsx_class_collector through parser helper methods - Fix confidence value type in detect_cross_file_conflicts (str→float)
…lict detection Revives PR tirth8205#61 (originally against v1.8.4 / f9f01ae) by manually reapplying its feature diff onto current upstream/main (392 commits of unrelated drift, including the parser/tools.py decompositions). Adds Tree-sitter-based CSS/SCSS parsing and a regex-based LESS parser, a STYLES edge type linking JSX/Vue class references to CSS selectors, an OVERRIDES edge type for same-file CSS specificity/!important/BEM override detection, and a POTENTIAL_CONFLICT edge type for cross-file selector collisions. Exposes five new query_graph patterns (styles_of, styled_by, conflicts_of, overrides_of, overridden_by) and CSS-aware review guidance. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hw3m91NAzZmXw9MHrvNnDB
…exing Address correctness issues in the CSS/STYLES linking: - Scope STYLES edges by imports, not global class-name match. A component now links to a selector only when the selector is in the same file or in a stylesheet the component actually imports. Record every imported stylesheet (module + plain side-effect `import './x.css'`) on the File node as `css_import_files`, resolved in the same path convention as node file_paths (normpath, no symlink canonicalization) so comparisons hold on symlinked repo roots. Applies to the static, Vue, and CSS-Module paths. - Index selectors by every bare class token via a single regex, so compound (`.btn.active`), descendant (`.card .btn`), and pseudo (`.btn:hover`, `.btn::before`) selectors all match a plain className. - Hoist the per-file CSS-module import map out of the module-node loop. - Correct the `_jsx_class_collector` docstring to describe its actual reset/consume behavior on the JS/TS path vs the early-returning Vue/Svelte paths. Tests cover import-scoping (positive + unimported-negative), same-file Vue scoping, and compound/descendant/pseudo indexing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
72558de to
6d8868d
Compare
|
Revived and rebased onto current
Full suite green (1437 passed), ruff + mypy clean on touched files. Happy to adjust the scoping heuristic if you'd prefer a different policy for global (non-module) CSS. |
Summary
[a,b,c], single-file override detection (specificity,!important, BEM, source order), custom properties,@media/@keyframes/@import, SCSS$variables/@mixin/@include/&nesting, Vue<style>block delegationclassNamefrom JSX/TSX andclassfrom Vue<template>, post-build linking pass connects components to CSS selectors, CSS Modules resolution (styles.foo→.foowith camelCase-to-kebab)POTENTIAL_CONFLICTedges with specificity comparison and confidence metadata@variables,.mixins(),@importstyles_of,styled_by,conflicts_ofNew Edge Types
OVERRIDESSTYLESPOTENTIAL_CONFLICTArchitecture
Two-phase approach keeps the parser stateless:
extrametadatalink_css_styles()anddetect_cross_file_conflicts()query the graph and create cross-file edgesBoth phases run automatically in
full_build()andincremental_update().Test Plan
ruff checkcleanmypycleanTestJSXClassExtraction— static className, CSS Module refs, dynamic skip, function attachmentTestVueTemplateClassExtraction— static class, dynamic:classskip, style+template coexistenceTestLESSParsing— selectors,@variables,@import,.mixins, language taggingTestCSSStylesLinking— cross-file STYLES edges, Vue same-file linking, missing selector no-opTestCrossFileConflicts— same-selector conflict, unique selector no-conflict, metadata validationTestCamelToKebab— camelCase conversion correctness