srcly 0.1.26__tar.gz → 0.1.27__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {srcly-0.1.26 → srcly-0.1.27}/PKG-INFO +1 -1
- {srcly-0.1.26 → srcly-0.1.27}/app/services/focus_overlay.py +8 -1
- srcly-0.1.27/app/services/python/python_analysis.py +313 -0
- srcly-0.1.27/app/services/typescript/typescript_analysis.py +948 -0
- srcly-0.1.27/app/static/assets/index-BD7BxeQJ.js +66 -0
- srcly-0.1.27/app/static/assets/index-BDq2TMkJ.css +1 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/index.html +2 -2
- {srcly-0.1.26 → srcly-0.1.27}/pyproject.toml +1 -1
- srcly-0.1.26/app/services/python/python_analysis.py +0 -317
- srcly-0.1.26/app/services/typescript/typescript_analysis.py +0 -1353
- srcly-0.1.26/app/static/assets/index-BeWzlQnV.css +0 -1
- srcly-0.1.26/app/static/assets/index-TkRIdY4e.js +0 -66
- {srcly-0.1.26 → srcly-0.1.27}/.gitignore +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/README.md +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/.gitignore +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/__init__.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/config.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/main.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/models.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/routers/analysis.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/routers/files.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/run.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/services/analysis.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/services/analysis_types.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/services/cache.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/services/css/css_analysis.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/services/data_flow_analysis.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/services/ipynb/ipynb_analysis.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/services/markdown/markdown_analysis.py +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/abap-BdImnpbu.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/actionscript-3-CfeIJUat.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/ada-bCR0ucgS.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/andromeeda-C-Jbm3Hp.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/angular-html-CU67Zn6k.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/angular-ts-BwZT4LLn.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/apache-Pmp26Uib.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/apex-DhZLUxFE.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/apl-dKokRX4l.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/applescript-Co6uUVPk.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/ara-BRHolxvo.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/asciidoc-Dv7Oe6Be.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/asm-D_Q5rh1f.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/astro-CbQHKStN.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/aurora-x-D-2ljcwZ.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/awk-DMzUqQB5.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/ayu-dark-Cv9koXgw.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/ballerina-BFfxhgS-.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/bat-BkioyH1T.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/beancount-k_qm7-4y.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/berry-D08WgyRC.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/bibtex-CHM0blh-.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/bicep-Bmn6On1c.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/blade-DVc8C-J4.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/bsl-BO_Y6i37.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/c-BIGW1oBm.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/cadence-Bv_4Rxtq.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/cairo-KRGpt6FW.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/catppuccin-frappe-DFWUc33u.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/catppuccin-latte-C9dUb6Cb.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/catppuccin-macchiato-DQyhUUbL.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/catppuccin-mocha-D87Tk5Gz.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/clarity-D53aC0YG.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/clojure-P80f7IUj.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/cmake-D1j8_8rp.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/cobol-nwyudZeR.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/codeowners-Bp6g37R7.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/codeql-DsOJ9woJ.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/coffee-Ch7k5sss.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/common-lisp-Cg-RD9OK.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/coq-DkFqJrB1.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/cpp-CofmeUqb.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/crystal-tKQVLTB8.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/csharp-CX12Zw3r.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/css-DPfMkruS.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/csv-fuZLfV_i.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/cue-D82EKSYY.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/cypher-COkxafJQ.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/d-85-TOEBH.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/dark-plus-eOWES_5F.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/dart-CF10PKvl.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/dax-CEL-wOlO.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/desktop-BmXAJ9_W.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/diff-D97Zzqfu.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/docker-BcOcwvcX.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/dotenv-Da5cRb03.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/dracula-BzJJZx-M.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/dracula-soft-BXkSAIEj.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/dream-maker-BtqSS_iP.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/edge-BkV0erSs.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/elixir-CDX3lj18.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/elm-DbKCFpqz.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/emacs-lisp-C9XAeP06.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/erb-BOJIQeun.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/erlang-DsQrWhSR.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/everforest-dark-BgDCqdQA.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/everforest-light-C8M2exoo.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/fennel-BYunw83y.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/fish-BvzEVeQv.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/fluent-C4IJs8-o.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/fortran-fixed-form-BZjJHVRy.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/fortran-free-form-D22FLkUw.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/fsharp-CXgrBDvD.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gdresource-B7Tvp0Sc.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gdscript-DTMYz4Jt.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gdshader-DkwncUOv.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/genie-D0YGMca9.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gherkin-DyxjwDmM.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/git-commit-F4YmCXRG.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/git-rebase-r7XF79zn.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/github-dark-DHJKELXO.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/github-dark-default-Cuk6v7N8.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/github-dark-dimmed-DH5Ifo-i.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/github-light-DAi9KRSo.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/github-light-default-D7oLnXFd.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/github-light-high-contrast-BfjtVDDH.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gleam-BspZqrRM.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/glimmer-js-Rg0-pVw9.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/glimmer-ts-U6CK756n.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/glsl-DplSGwfg.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gnuplot-DdkO51Og.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/go-Dn2_MT6a.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/graphql-ChdNCCLP.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/groovy-gcz8RCvz.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gruvbox-dark-medium-GsRaNv29.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gruvbox-dark-soft-CVdnzihN.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gruvbox-light-hard-CH1njM8p.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gruvbox-light-medium-DRw_LuNl.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/gruvbox-light-soft-hJgmCMqR.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/hack-CaT9iCJl.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/haml-B8DHNrY2.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/handlebars-BL8al0AC.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/haskell-Df6bDoY_.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/haxe-CzTSHFRz.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/hcl-BWvSN4gD.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/hjson-D5-asLiD.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/hlsl-D3lLCCz7.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/houston-DnULxvSX.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/html-GMplVEZG.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/html-derivative-BFtXZ54Q.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/http-jrhK8wxY.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/hurl-irOxFIW8.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/hxml-Bvhsp5Yf.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/hy-DFXneXwc.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/imba-DGztddWO.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/ini-BEwlwnbL.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/java-CylS5w8V.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/javascript-wDzz0qaB.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/jinja-4LBKfQ-Z.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/jison-wvAkD_A8.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/json-Cp-IABpG.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/json5-C9tS-k6U.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/jsonc-Des-eS-w.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/jsonl-DcaNXYhu.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/jsonnet-DFQXde-d.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/jssm-C2t-YnRu.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/jsx-g9-lgVsj.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/julia-C8NyazO9.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/kanagawa-dragon-CkXjmgJE.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/kanagawa-lotus-CfQXZHmo.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/kanagawa-wave-DWedfzmr.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/kdl-DV7GczEv.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/kotlin-BdnUsdx6.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/kusto-BvAqAH-y.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/laserwave-DUszq2jm.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/latex-BUKiar2Z.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/lean-DP1Csr6i.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/less-B1dDrJ26.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/light-plus-B7mTdjB0.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/liquid-DYVedYrR.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/llvm-BtvRca6l.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/log-2UxHyX5q.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/logo-BtOb2qkB.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/lua-BbnMAYS6.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/luau-CXu1NL6O.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/make-CHLpvVh8.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/markdown-Cvjx9yec.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/marko-CPi9NSCl.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/material-theme-D5KoaKCx.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/material-theme-darker-BfHTSMKl.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/material-theme-lighter-B0m2ddpp.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/material-theme-ocean-CyktbL80.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/material-theme-palenight-Csfq5Kiy.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/matlab-D7o27uSR.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/mdc-DUICxH0z.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/mdx-Cmh6b_Ma.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/mermaid-DKYwYmdq.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/min-dark-CafNBF8u.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/min-light-CTRr51gU.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/mipsasm-CKIfxQSi.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/mojo-1DNp92w6.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/monokai-D4h5O-jR.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/move-Bu9oaDYs.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/narrat-DRg8JJMk.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/nextflow-CUEJCptM.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/nginx-DknmC5AR.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/night-owl-C39BiMTA.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/nim-CVrawwO9.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/nix-BbRYJGeE.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/nord-Ddv68eIx.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/nushell-C-sUppwS.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/objective-c-DXmwc3jG.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/objective-cpp-CLxacb5B.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/ocaml-C0hk2d4L.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/one-dark-pro-DVMEJ2y_.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/one-light-PoHY5YXO.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/pascal-D93ZcfNL.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/perl-C0TMdlhV.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/php-CDn_0X-4.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/pkl-u5AG7uiY.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/plastic-3e1v2bzS.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/plsql-ChMvpjG-.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/po-BTJTHyun.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/poimandres-CS3Unz2-.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/polar-C0HS_06l.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/postcss-CXtECtnM.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/powerquery-CEu0bR-o.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/powershell-Dpen1YoG.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/prisma-Dd19v3D-.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/prolog-CbFg5uaA.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/proto-DyJlTyXw.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/pug-CGlum2m_.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/puppet-BMWR74SV.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/purescript-CklMAg4u.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/python-B6aJPvgy.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/qml-3beO22l8.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/qmldir-C8lEn-DE.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/qss-IeuSbFQv.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/r-DiinP2Uv.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/racket-BqYA7rlc.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/raku-DXvB9xmW.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/razor-WgofotgN.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/red-bN70gL4F.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/reg-C-SQnVFl.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/regexp-CDVJQ6XC.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/rel-C3B-1QV4.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/riscv-BM1_JUlF.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/rose-pine-BHrmToEH.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/rose-pine-dawn-CnK8MTSM.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/rose-pine-moon-NleAzG8P.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/rosmsg-BJDFO7_C.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/rst-B0xPkSld.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/ruby-BvKwtOVI.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/rust-B1yitclQ.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/sas-cz2c8ADy.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/sass-Cj5Yp3dK.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/scala-C151Ov-r.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/scheme-C98Dy4si.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/scss-OYdSNvt2.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/sdbl-DVxCFoDh.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/shaderlab-Dg9Lc6iA.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/shellscript-Yzrsuije.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/shellsession-BADoaaVG.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/slack-dark-BthQWCQV.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/slack-ochin-DqwNpetd.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/smalltalk-BERRCDM3.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/snazzy-light-Bw305WKR.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/solarized-dark-DXbdFlpD.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/solarized-light-L9t79GZl.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/solidity-BbcW6ACK.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/soy-Brmx7dQM.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/sparql-rVzFXLq3.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/splunk-BtCnVYZw.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/sql-BLtJtn59.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/ssh-config-_ykCGR6B.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/stata-BH5u7GGu.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/stylus-BEDo0Tqx.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/svelte-3Dk4HxPD.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/swift-Dg5xB15N.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/synthwave-84-CbfX1IO0.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/system-verilog-CnnmHF94.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/systemd-4A_iFExJ.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/talonscript-CkByrt1z.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/tasl-QIJgUcNo.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/tcl-dwOrl1Do.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/templ-W15q3VgB.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/terraform-BETggiCN.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/tex-Cppo0RY3.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/tokyo-night-hegEt444.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/toml-vGWfd6FD.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/ts-tags-zn1MmPIZ.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/tsv-B_m7g4N7.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/tsx-COt5Ahok.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/turtle-BsS91CYL.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/twig-CO9l9SDP.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/typescript-BPQ3VLAy.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/typespec-Df68jz8_.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/typst-DHCkPAjA.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/v-BcVCzyr7.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vala-CsfeWuGM.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vb-D17OF-Vu.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/verilog-BQ8w6xss.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vesper-DU1UobuO.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vhdl-CeAyd5Ju.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/viml-CJc9bBzg.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vitesse-black-Bkuqu6BP.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vitesse-dark-D0r3Knsf.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vitesse-light-CVO1_9PV.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vue-CCoi5OLL.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vue-html-DAAvJJDi.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vue-vine-_Ih-lPRR.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/vyper-CDx5xZoG.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/wasm-CG6Dc4jp.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/wasm-MzD3tlZU.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/wenyan-BV7otONQ.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/wgsl-Dx-B1_4e.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/wikitext-BhOHFoWU.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/wit-5i3qLPDT.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/wolfram-lXgVvXCa.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/xml-sdJ4AIDG.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/xsl-CtQFsRM5.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/yaml-Buea-lGh.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/zenscript-DVFEvuxE.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/assets/zig-VOosw3JB.js +0 -0
- {srcly-0.1.26 → srcly-0.1.27}/app/static/vite.svg +0 -0
|
@@ -1034,9 +1034,16 @@ def compute_focus_overlay(
|
|
|
1034
1034
|
usage_fn_scope_id = u.containing_fn_scope_id
|
|
1035
1035
|
usage_fn_chain = set(_ancestor_chain(usage_fn_scope_id))
|
|
1036
1036
|
|
|
1037
|
+
|
|
1037
1038
|
def_chain = set(_ancestor_chain(def_scope.id))
|
|
1038
1039
|
|
|
1039
|
-
|
|
1040
|
+
# START FIX: If the definition is within the current focus range, treat as local.
|
|
1041
|
+
definition_in_focus = (focus_start_line <= d.def_line <= focus_end_line)
|
|
1042
|
+
|
|
1043
|
+
if definition_in_focus:
|
|
1044
|
+
category = "local"
|
|
1045
|
+
tooltip = f"Local declaration (line {d.def_line})"
|
|
1046
|
+
elif usage_fn_scope_id in def_chain:
|
|
1040
1047
|
category = "local"
|
|
1041
1048
|
tooltip = f"Local declaration (line {d.def_line})"
|
|
1042
1049
|
elif def_scope.id in usage_fn_chain and def_scope.id != global_scope.id:
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import tree_sitter_python as tspython
|
|
2
|
+
from tree_sitter import Language, Parser, Node
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from app.services.analysis_types import FileMetrics, FunctionMetrics
|
|
6
|
+
|
|
7
|
+
# Load Python grammar
|
|
8
|
+
PYTHON_LANGUAGE = Language(tspython.language())
|
|
9
|
+
|
|
10
|
+
class PythonTreeSitterAnalyzer:
|
|
11
|
+
def __init__(self):
|
|
12
|
+
self.parser = Parser(PYTHON_LANGUAGE)
|
|
13
|
+
|
|
14
|
+
def analyze_file(self, file_path: str) -> FileMetrics:
|
|
15
|
+
with open(file_path, 'rb') as f:
|
|
16
|
+
content = f.read()
|
|
17
|
+
|
|
18
|
+
tree = self.parser.parse(content)
|
|
19
|
+
|
|
20
|
+
lines = content.splitlines()
|
|
21
|
+
nloc = len([l for l in lines if l.strip()])
|
|
22
|
+
|
|
23
|
+
# Initialize file-level counters
|
|
24
|
+
self._file_comment_lines = 0
|
|
25
|
+
self._file_todo_count = 0
|
|
26
|
+
self._file_classes_count = 0
|
|
27
|
+
self._file_python_import_count = 0
|
|
28
|
+
self._file_max_nesting_depth = 0
|
|
29
|
+
|
|
30
|
+
# Run single-pass traversal
|
|
31
|
+
top_level_functions = []
|
|
32
|
+
self._scan_tree(tree.root_node, top_level_functions, [], 0)
|
|
33
|
+
|
|
34
|
+
# Calculate imports separately (logic is distinct and fast enough to keep separate/clean)
|
|
35
|
+
import_scope = self._compute_import_scope(tree.root_node, content)
|
|
36
|
+
if import_scope is not None:
|
|
37
|
+
top_level_functions.insert(0, import_scope)
|
|
38
|
+
|
|
39
|
+
# Average complexity (top-level only, matching original behavior)
|
|
40
|
+
avg_complexity = 0.0
|
|
41
|
+
if top_level_functions:
|
|
42
|
+
avg_complexity = sum(f.cyclomatic_complexity for f in top_level_functions) / len(top_level_functions)
|
|
43
|
+
|
|
44
|
+
# File level comment density
|
|
45
|
+
comment_density = self._file_comment_lines / nloc if nloc > 0 else 0.0
|
|
46
|
+
|
|
47
|
+
# Aggregate function metrics for file summary
|
|
48
|
+
# Note: Previous implementation calculated avg function length based on top-level functions?
|
|
49
|
+
# "total_function_length = sum(f.nloc for f in functions)"
|
|
50
|
+
# Yes, purely top-level iteration.
|
|
51
|
+
total_function_length = sum(f.nloc for f in top_level_functions)
|
|
52
|
+
average_function_length = total_function_length / len(top_level_functions) if top_level_functions else 0.0
|
|
53
|
+
parameter_count = sum(f.parameter_count for f in top_level_functions)
|
|
54
|
+
|
|
55
|
+
return FileMetrics(
|
|
56
|
+
nloc=nloc,
|
|
57
|
+
average_cyclomatic_complexity=avg_complexity,
|
|
58
|
+
function_list=top_level_functions,
|
|
59
|
+
filename=file_path,
|
|
60
|
+
comment_lines=self._file_comment_lines,
|
|
61
|
+
comment_density=comment_density,
|
|
62
|
+
max_nesting_depth=self._file_max_nesting_depth,
|
|
63
|
+
average_function_length=average_function_length,
|
|
64
|
+
parameter_count=parameter_count,
|
|
65
|
+
todo_count=self._file_todo_count,
|
|
66
|
+
classes_count=self._file_classes_count,
|
|
67
|
+
# Initialize other fields to valid defaults
|
|
68
|
+
tsx_nesting_depth=0,
|
|
69
|
+
tsx_render_branching_count=0,
|
|
70
|
+
tsx_react_use_effect_count=0,
|
|
71
|
+
tsx_anonymous_handler_count=0,
|
|
72
|
+
tsx_prop_count=0,
|
|
73
|
+
ts_any_usage_count=0,
|
|
74
|
+
ts_ignore_count=0,
|
|
75
|
+
ts_import_coupling_count=0,
|
|
76
|
+
python_import_count=self._file_python_import_count,
|
|
77
|
+
tsx_hardcoded_string_volume=0,
|
|
78
|
+
tsx_duplicated_string_count=0,
|
|
79
|
+
ts_type_interface_count=0,
|
|
80
|
+
ts_export_count=0,
|
|
81
|
+
md_data_url_count=0
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def _scan_tree(
|
|
85
|
+
self,
|
|
86
|
+
node: Node,
|
|
87
|
+
parent_list: List[FunctionMetrics],
|
|
88
|
+
active_scopes: List[dict],
|
|
89
|
+
current_nesting: int
|
|
90
|
+
):
|
|
91
|
+
"""
|
|
92
|
+
Single-pass visitor to collect metrics.
|
|
93
|
+
|
|
94
|
+
parent_list: List to append new FunctionMetrics to (children of parent scope or top level).
|
|
95
|
+
active_scopes: Stack of dicts: {'metrics': FunctionMetrics, 'base_nesting': int}
|
|
96
|
+
current_nesting: Current nesting depth relative to file root.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
node_type = node.type
|
|
100
|
+
|
|
101
|
+
# 1. Update File Metrics
|
|
102
|
+
if node_type == 'class_definition':
|
|
103
|
+
self._file_classes_count += 1
|
|
104
|
+
elif node_type in {'import_statement', 'import_from_statement'}:
|
|
105
|
+
self._file_python_import_count += 1
|
|
106
|
+
|
|
107
|
+
# 2. Check Nesting Depth for File
|
|
108
|
+
# File max nesting is just max of current_nesting encountered
|
|
109
|
+
# Wait, if we are at 'if' (nesting), current_nesting is passed as incremented.
|
|
110
|
+
# But we need to record it.
|
|
111
|
+
# Actually, let's track max seen.
|
|
112
|
+
is_nesting_node = node_type in {
|
|
113
|
+
'if_statement', 'for_statement', 'while_statement', 'try_statement',
|
|
114
|
+
'with_statement', 'match_statement'
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
# Update nesting for next recursion
|
|
118
|
+
next_nesting = current_nesting
|
|
119
|
+
if is_nesting_node:
|
|
120
|
+
next_nesting += 1
|
|
121
|
+
|
|
122
|
+
if next_nesting > self._file_max_nesting_depth:
|
|
123
|
+
self._file_max_nesting_depth = next_nesting
|
|
124
|
+
|
|
125
|
+
# 3. Update Active Scopes (Nesting & Comments)
|
|
126
|
+
if node_type == 'comment':
|
|
127
|
+
lines = (node.end_point.row - node.start_point.row + 1)
|
|
128
|
+
text = node.text.decode('utf-8', errors='ignore')
|
|
129
|
+
is_todo = 'TODO' in text or 'FIXME' in text
|
|
130
|
+
|
|
131
|
+
self._file_comment_lines += lines
|
|
132
|
+
if is_todo:
|
|
133
|
+
self._file_todo_count += 1
|
|
134
|
+
|
|
135
|
+
for scope in active_scopes:
|
|
136
|
+
scope['metrics'].comment_lines += lines
|
|
137
|
+
if is_todo:
|
|
138
|
+
scope['metrics'].todo_count += 1
|
|
139
|
+
|
|
140
|
+
# Update Max Nesting for Scopes
|
|
141
|
+
if is_nesting_node:
|
|
142
|
+
for scope in active_scopes:
|
|
143
|
+
# Depth relative to where the scope started
|
|
144
|
+
depth = next_nesting - scope['base_nesting']
|
|
145
|
+
if depth > scope['metrics'].max_nesting_depth:
|
|
146
|
+
scope['metrics'].max_nesting_depth = depth
|
|
147
|
+
|
|
148
|
+
# 4. Complexity (Applies to immediate scope only)
|
|
149
|
+
# Complexity types
|
|
150
|
+
if active_scopes:
|
|
151
|
+
current_scope = active_scopes[-1]['metrics']
|
|
152
|
+
if node_type in {
|
|
153
|
+
'if_statement', 'for_statement', 'while_statement', 'except_clause',
|
|
154
|
+
'with_statement', 'match_statement', 'case_pattern'
|
|
155
|
+
}:
|
|
156
|
+
current_scope.cyclomatic_complexity += 1
|
|
157
|
+
elif node_type == 'boolean_operator':
|
|
158
|
+
# Check text for 'and'/'or'
|
|
159
|
+
# Optimization: check text content
|
|
160
|
+
text = node.text.decode('utf-8')
|
|
161
|
+
if 'and' in text or 'or' in text:
|
|
162
|
+
current_scope.cyclomatic_complexity += 1
|
|
163
|
+
|
|
164
|
+
# 5. Handle Scope Creation
|
|
165
|
+
scope_created = False
|
|
166
|
+
target_list_for_children = parent_list
|
|
167
|
+
|
|
168
|
+
# Define scope types
|
|
169
|
+
is_scope = node_type in {
|
|
170
|
+
'function_definition',
|
|
171
|
+
'class_definition',
|
|
172
|
+
'lambda',
|
|
173
|
+
'async_function_definition'
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if is_scope:
|
|
177
|
+
new_metrics = self._create_scope_metrics(node)
|
|
178
|
+
parent_list.append(new_metrics)
|
|
179
|
+
|
|
180
|
+
# Function complexity default is 1
|
|
181
|
+
new_metrics.cyclomatic_complexity = 1
|
|
182
|
+
|
|
183
|
+
new_scope_ctx = {
|
|
184
|
+
'metrics': new_metrics,
|
|
185
|
+
'base_nesting': current_nesting
|
|
186
|
+
# Note: 'base_nesting' is the ambient nesting level AT the function definition.
|
|
187
|
+
# Content inside will start contributing to depth from there.
|
|
188
|
+
}
|
|
189
|
+
active_scopes.append(new_scope_ctx)
|
|
190
|
+
target_list_for_children = new_metrics.children
|
|
191
|
+
scope_created = True
|
|
192
|
+
|
|
193
|
+
# Recurse
|
|
194
|
+
for child in node.children:
|
|
195
|
+
# Optimization: If we just created a scope, we are passing its children list.
|
|
196
|
+
# But we must treat the child as children of the node.
|
|
197
|
+
# The 'target_list_for_children' is where the child's *scopes* should act effectively.
|
|
198
|
+
# Wait, `scan_tree` adds *scopes* to `parent_list`.
|
|
199
|
+
# If `child` is an `if_statement` (not a scope), it shouldn't be added to `parent_list`.
|
|
200
|
+
# `scan_tree` ONLY appends to `parent_list` IF `is_scope` is true.
|
|
201
|
+
# So passing `target_list_for_children` is safe.
|
|
202
|
+
self._scan_tree(child, target_list_for_children, active_scopes, next_nesting)
|
|
203
|
+
|
|
204
|
+
if scope_created:
|
|
205
|
+
active_scopes.pop()
|
|
206
|
+
|
|
207
|
+
def _create_scope_metrics(self, node: Node) -> FunctionMetrics:
|
|
208
|
+
name = self._get_scope_name(node)
|
|
209
|
+
start_line = node.start_point.row + 1
|
|
210
|
+
end_line = node.end_point.row + 1
|
|
211
|
+
nloc = end_line - start_line + 1
|
|
212
|
+
|
|
213
|
+
# Parameter count is fast enough to compute locally
|
|
214
|
+
parameter_count = self._count_parameters(node)
|
|
215
|
+
|
|
216
|
+
return FunctionMetrics(
|
|
217
|
+
name=name,
|
|
218
|
+
cyclomatic_complexity=0, # Will be accumulated
|
|
219
|
+
nloc=nloc,
|
|
220
|
+
start_line=start_line,
|
|
221
|
+
end_line=end_line,
|
|
222
|
+
parameter_count=parameter_count,
|
|
223
|
+
max_nesting_depth=0, # Will be accumulated
|
|
224
|
+
comment_lines=0, # Will be accumulated
|
|
225
|
+
todo_count=0, # Will be accumulated
|
|
226
|
+
origin_type=node.type
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
def _get_scope_name(self, node: Node) -> str:
|
|
230
|
+
if node.type in {'function_definition', 'class_definition', 'async_function_definition'}:
|
|
231
|
+
name_node = node.child_by_field_name('name')
|
|
232
|
+
if name_node:
|
|
233
|
+
prefix = ""
|
|
234
|
+
if node.type == 'class_definition': prefix = "(class) "
|
|
235
|
+
if node.type == 'async_function_definition': prefix = "(async) "
|
|
236
|
+
return f"{prefix}{name_node.text.decode('utf-8')}"
|
|
237
|
+
|
|
238
|
+
elif node.type == 'lambda':
|
|
239
|
+
return "(lambda)"
|
|
240
|
+
|
|
241
|
+
return "(anonymous)"
|
|
242
|
+
|
|
243
|
+
def _count_parameters(self, node: Node) -> int:
|
|
244
|
+
params_node = node.child_by_field_name('parameters')
|
|
245
|
+
if params_node:
|
|
246
|
+
count = 0
|
|
247
|
+
for child in params_node.children:
|
|
248
|
+
if child.type in {'identifier', 'typed_parameter', 'default_parameter', 'typed_default_parameter', 'list_splat_pattern', 'dictionary_splat_pattern'}:
|
|
249
|
+
count += 1
|
|
250
|
+
return count
|
|
251
|
+
return 0
|
|
252
|
+
|
|
253
|
+
def _compute_import_scope(self, root_node: Node, content: bytes) -> FunctionMetrics | None:
|
|
254
|
+
"""
|
|
255
|
+
Create a synthetic top-level scope representing import statements.
|
|
256
|
+
Kept separate as it requires specific logic for contiguous block merging.
|
|
257
|
+
"""
|
|
258
|
+
import_spans: List[tuple[int, int]] = []
|
|
259
|
+
lines = content.splitlines()
|
|
260
|
+
|
|
261
|
+
def only_blank_lines_between(end_line: int, start_line: int) -> bool:
|
|
262
|
+
if start_line <= end_line + 1:
|
|
263
|
+
return True
|
|
264
|
+
for line_no in range(end_line + 1, start_line):
|
|
265
|
+
idx = line_no - 1
|
|
266
|
+
if 0 <= idx < len(lines):
|
|
267
|
+
if lines[idx].strip():
|
|
268
|
+
return False
|
|
269
|
+
return True
|
|
270
|
+
|
|
271
|
+
def traverse(n: Node) -> None:
|
|
272
|
+
if n.type in {"import_statement", "import_from_statement"}:
|
|
273
|
+
start_line = n.start_point.row + 1
|
|
274
|
+
end_line = n.end_point.row + 1
|
|
275
|
+
import_spans.append((start_line, end_line))
|
|
276
|
+
for child in n.children:
|
|
277
|
+
traverse(child)
|
|
278
|
+
|
|
279
|
+
traverse(root_node)
|
|
280
|
+
|
|
281
|
+
if not import_spans:
|
|
282
|
+
return None
|
|
283
|
+
|
|
284
|
+
import_spans.sort(key=lambda s: (s[0], s[1]))
|
|
285
|
+
total_import_loc = sum(e - s + 1 for s, e in import_spans)
|
|
286
|
+
|
|
287
|
+
blocks: List[tuple[int, int, int]] = []
|
|
288
|
+
cur_s, cur_e = import_spans[0]
|
|
289
|
+
cur_loc = cur_e - cur_s + 1
|
|
290
|
+
for s, e in import_spans[1:]:
|
|
291
|
+
if only_blank_lines_between(cur_e, s):
|
|
292
|
+
cur_e = max(cur_e, e)
|
|
293
|
+
cur_loc += (e - s + 1)
|
|
294
|
+
else:
|
|
295
|
+
blocks.append((cur_s, cur_e, cur_loc))
|
|
296
|
+
cur_s, cur_e = s, e
|
|
297
|
+
cur_loc = e - s + 1
|
|
298
|
+
blocks.append((cur_s, cur_e, cur_loc))
|
|
299
|
+
|
|
300
|
+
block_s, block_e, _ = max(blocks, key=lambda b: (b[2], -b[0]))
|
|
301
|
+
|
|
302
|
+
return FunctionMetrics(
|
|
303
|
+
name="(imports)",
|
|
304
|
+
cyclomatic_complexity=0,
|
|
305
|
+
nloc=total_import_loc,
|
|
306
|
+
start_line=block_s,
|
|
307
|
+
end_line=block_e,
|
|
308
|
+
parameter_count=0,
|
|
309
|
+
max_nesting_depth=0,
|
|
310
|
+
comment_lines=0,
|
|
311
|
+
todo_count=0,
|
|
312
|
+
origin_type="imports",
|
|
313
|
+
)
|