https://github.com/scottrogowski/code2flow Skip to content Sign up * Why GitHub? + Features + Mobile + Actions + Codespaces + Packages + Security + Code review + Issues + Integrations + GitHub Sponsors + Customer stories * Team * Enterprise * Explore + Explore GitHub + Learn and contribute + Topics + Collections + Trending + Learning Lab + Open source guides + Connect with others + The ReadME Project + Events + Community forum + GitHub Education + GitHub Stars program * Marketplace * Pricing + Plans + Compare plans + Contact Sales + Education [ ] * # In this repository All GitHub | Jump to | * No suggested jump to results * # In this repository All GitHub | Jump to | * # In this user All GitHub | Jump to | * # In this repository All GitHub | Jump to | Sign in Sign up {{ message }} scottrogowski / code2flow Public * * Notifications * Star 1.3k * Fork 155 * Pretty good call graphs for dynamic languages MIT License 1.3k stars 155 forks Star Notifications * Code * Issues 3 * Pull requests 0 * Actions * Projects 0 * Wiki * Security * Insights More * Code * Issues * Pull requests * Actions * Projects * Wiki * Security * Insights master Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show Loading {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default Loading View all tags 7 branches 0 tags Code Loading Latest commit @scottrogowski scottrogowski and Scott December fixes (#35) ... 2bd6adf Dec 10, 2021 December fixes (#35) * improve dependency robustness. Fix Python import bug. Small text improvements * include acorn dependency * add acorn package * add python test for relative paths * fix eof newlines Co-authored-by: Scott 2bd6adf Git stats * 109 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .github modify gitignore. Add changelog. Move funding Apr 23, 2021 assets README cleanup + pip install. Add build to Makefile. Update image. Jun 27, 2021 code2flow December fixes (#35) Dec 10, 2021 tests December fixes (#35) Dec 10, 2021 .gitignore Js (#23) Jun 15, 2021 CHANGELOG.md release 2.3.0 Oct 11, 2021 LICENSE Start of major cleanup. Linter is much less noisy. Running for at lea... Apr 12, 2021 MANIFEST.in More robust troubleshooting (#34) Oct 11, 2021 Makefile README cleanup + pip install. Add build to Makefile. Update image. Jun 27, 2021 README.md December fixes (#35) Dec 10, 2021 c2f Windows (#25) Jun 15, 2021 make_expected.py Php + Ruby (#26) Jun 24, 2021 requirements_dev.txt Js (#23) Jun 15, 2021 setup.py More robust troubleshooting (#34) Oct 11, 2021 View code [ ] Installation Usage How code2flow works Why is it impossible to generate a perfect call graph? Known limitations How to contribute License Acknowledgements Unrelated projects Unit tests Feedback / Contact Feature Requests README.md code2flow logo Version 2.3.0 Build passing Coverage 100% License MIT Code2flow generates call graphs for dynamic programming language. Code2flow supports Python, Javascript, Ruby, and PHP. The basic algorithm is simple: 1. Translate your source files into ASTs. 2. Find all function definitions. 3. Determine where those functions are called. 4. Connect the dots. Code2flow is useful for: * Untangling spaghetti code. * Identifying orphaned functions. * Getting new developers up to speed. Code2flow will provide a pretty good estimate of your project's structure. No algorithm can generate a perfect call graph for a dynamic language - even less so if that language is duck-typed. See the known limitations in the section below. (Below: Code2flow running on itself (excl javascript, PHP, & Ruby for clarity)) code2flow running against itself Installation pip3 install code2flow If you don't have it already, you will also need to install graphviz. Installation instructions can be found here. Additionally, depending on the language you want to parse, you may need to install additional dependencies: * Javascript: Acorn * Ruby: Parser * PHP: PHP-Parser * Python: No extra dependencies needed Usage To generate a DOT file run something like: code2flow mypythonfile.py Or, for javascript: code2flow myjavascriptfile.js You can also specify multiple files or import directories: code2flow project/directory/source_a.js project/directory/source_b.js code2flow project/directory/*.js code2flow project/directory --language js There are a ton of command line options, to see them all, run: code2flow --help How code2flow works Code2flow approximates the structure of projects in dynamic languages. It is not possible to generate a perfect callgraph for a dynamic language. Detailed algorithm: 1. Generate an AST of the source code 2. Recursively separate groups and nodes. Groups are files, modules, or classes. More precisely, groups are namespaces where functions live. Nodes are the functions themselves. 3. For all nodes, identify function calls in those nodes. 4. For all nodes, identify in-scope variables. Attempt to connect those variables to specific nodes and groups. This is where there is some ambiguity in the algorithm because it is possible to know the types of variables in dynamic languages. So, instead, heuristics must be used. 5. For all calls in all nodes, attempt to find a match from the in-scope variables. This will be an edge. 6. If a definitive match from in-scope variables cannot be found, attempt to find a single match from all other groups and nodes. 7. Trim orphaned nodes and groups. 8. Output results. Why is it impossible to generate a perfect call graph? Consider this toy example in Python def func_factory(param): if param < .5: return func_a else: return func_b func = func_factory(important_variable) func() We have no way of knowing whether func will point to func_a or func_b until runtime. In practice, ambiguity like this is common and is present in most non-trivial applications. Known limitations Code2flow is internally powered by ASTs. Most limitations stem from a token not being named what code2flow expects it to be named. * All functions without definitions are skipped. This most often happens when a file is not included. * Functions with identical names in different namespaces are (loudly) skipped. E.g. If you have two classes with identically named methods, code2flow cannot distinguish between these and skips them. * Imported functions from outside of your project directory (including from standard libraries) which share names with your defined functions may not be handled correctly. Instead when you call the imported function, code2flow will link to your local functions. E.g. if you have a function "search()" and call, "import searcher; searcher.search()", code2flow may link (incorrectly) to your defined function. * Anonymous or generated functions are skipped. This includes lambdas and factories. * If a function is renamed, either explicitly or by being passed around as a parameter, it will be skipped. How to contribute 1. Open an issue: Code2flow is not perfect and there is a lot that can be improved. If you find a problem parsing your source that you can identify with a simplified example, please open an issue. 2. Create a PR: Even better, if you have a fix for the issue you identified that passes unit tests, please open a PR. 3. Add a language: While dense, each language implementation is between 250-400 lines of code including comments. If you want to implement another language, the existing implementations can be your guide. License Code2flow is licensed under the MIT license. Prior to the rewrite in April 2021, code2flow was licensed under LGPL. The last commit under that license was 24b2cb854c6a872ba6e17409fbddb6659bf64d4c. The April 2021 rewrite was substantial so it's probably reasonable to treat code2flow as completely MIT-licensed. Acknowledgements * In mid-2021, Code2flow was rewritten and two new languages were added. This was prompted and financially supported by the Sider Corporation. * The code2flow pip name was graciouly transferred to this project from Dheeraj Nair. He was using it for his own (unrelated) code2flow project. * Many others have contributed through bug fixes, cleanups, and identifying issues. Thank you!!! Unrelated projects The name, "code2flow", has been used for several unrelated projects. Specifically, the domain, code2flow.com, has no association with this project. I've never heard anything from them and it doesn't appear like they use anything from here. Unit tests Test coverage is 100%. To run: pip install -r requirements_dev.txt make test Feedback / Contact Please do email! scottmrogowski@gmail.com Feature Requests Email me. At any time, I'm spread thin across a lot of projects so I will, unfortunately, turn down most requests. However, I am open to paid development for compelling features. About Pretty good call graphs for dynamic languages Resources Readme License MIT License Releases No releases published Sponsor this project Sponsor Learn more about GitHub Sponsors Packages 0 No packages published Used by 5 * @yunisdev * @JustinGOSSES * @petermat * @leolle * @chrismeyersfsu Contributors 6 * @scottrogowski * @scott-utilityapi * @toelke * @techieshark * @klaernie * @suetsuguk Languages * Python 46.9% * JavaScript 28.6% * PHP 18.7% * Ruby 5.8% * (c) 2021 GitHub, Inc. * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can't perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.