{"id":19152586,"url":"https://github.com/bamless/pulsar","last_synced_at":"2026-03-19T08:23:43.733Z","repository":{"id":114070557,"uuid":"340907346","full_name":"bamless/pulsar","owner":"bamless","description":"Static analyzer for the J* language","archived":false,"fork":false,"pushed_at":"2025-01-06T18:37:15.000Z","size":118,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-22T21:15:15.086Z","etag":null,"topics":["jstar","language-dynamic","linter","programming-language","pulsar","scripting-language","static-analysis","static-analyzer"],"latest_commit_sha":null,"homepage":"https://github.com/bamless/jstar","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bamless.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-21T13:25:16.000Z","updated_at":"2025-01-06T18:37:20.000Z","dependencies_parsed_at":"2025-01-03T18:44:09.754Z","dependency_job_id":"6c716161-2aaa-4892-ac9d-7e55bf132f72","html_url":"https://github.com/bamless/pulsar","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/bamless/pulsar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bamless%2Fpulsar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bamless%2Fpulsar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bamless%2Fpulsar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bamless%2Fpulsar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bamless","download_url":"https://codeload.github.com/bamless/pulsar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bamless%2Fpulsar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29976272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T16:35:47.903Z","status":"ssl_error","status_checked_at":"2026-03-01T16:35:44.899Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jstar","language-dynamic","linter","programming-language","pulsar","scripting-language","static-analysis","static-analyzer"],"created_at":"2024-11-09T08:18:25.904Z","updated_at":"2026-03-01T17:03:54.614Z","avatar_url":"https://github.com/bamless.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pulsar: a static analyzer for the J* language\n\nPulsar is a static analyzer and linter for the [J*](https://github.com/bamless/jstar) language\nwritten in **J\\***.  \nIt can be used either as a standalone application, or through  Visual Studio Code via the \n[extension](https://marketplace.visualstudio.com/items?itemName=bamless.vsc-jstar-extension\u0026utm_source=VSCode.pro\u0026utm_campaign=AhmadAwais).\n\n## Supported features\n\nThe analysis of source files is broken down into multiple passes each reporting a specific class of\nerrors. Each pass can be disabled at will, and the behaviour of some of them can be changed by\npassing extra command line options. To list all available options simply pass the `-h` flag to\npulsar.\n\n### Syntax analysis pass\nOr more simply, the parser. This reports syntax errors and some more semantic ones like assignment \nto a non-lvalue expression. This pass does exactly the same things that the **J\\*** runtime parser\nalready does, and its main use is to obtain a correctly formed parse tree on which to apply \nsubsequent passses. If this pass fails with an error, no other pass will be executed, as we do not\nsupport partial parsing of source code. Obviously, this pass can't be disabled.\n\n### Semantic checking pass\nThis pass performs the same checks that the **J\\*** runtime compiler already does, such as unpacking\ndeclarations/assignments consistency, usage of break/continue inside loops and checking that return\nstatements are inside functions. This pass can't be disabled, as source files that don't pass these\nchecks are not considered valid **J\\*** source files.\n\n### Variable resolution pass\nThis pass is responsible for checking variable declarations and their use. It makes sure that\nvariables respect scoping rules and that are declared before usage. It also checks for possibly\nuninitialized variables. A variable is considered uninitialized if its declaration doesn't have an \ninitializer and its not assigned a value in all execution paths prior to its usage. Another check \nthat is performed is the checking of declaration before usage of `static` global variables.  \nThis pass can be completely disabled by passing the `-v, --no-variable-resolution` option.  \nBy passing the `-g, --no-redefined-globals` option, this pass will not check for redefinition of global\nvariables, as they are technically allowed by the language.  \nExamples:\n\nresolve.jsr:\n```lua\nvar a\n\nif x\n    a = 49\nelse\n    print(\"Don't initialize `a`\")\nend\n\nprint(a)\n\nfun foo()\n    print(bar)\nend\n\nstatic var bar = \"bar\"\n```\noutput:\n```\nAnalyzing resolve.jsr...\nFile resolve.jsr [line 3]:\n\nif x\n   ^\nCannot resolve name 'x'\nFile resolve.jsr [line 9]:\n\nprint(a)\n      ^\nVariable 'a' (declared at line 1) may be uninitialized\nFile resolve.jsr [line 12]:\n\n    print(bar)\n          ^~~\nStatic name 'bar' referenced before declaration (line 15)\n```\n\n### Unused variables pass\nThis pass checks that all declared local variables (or static global ones) are actually used in the\nprogram. Global variables are not checked as they form the API of the module and are accessible from\nthe outside. To make pulsar ignore a specific variable and not report an error, append a trailing \nunderscore to its name.  \nThis pass can be disabled by passing the `-u, --no-unused` command line option.  \nBy passing the `-a, --no-unused-args` option, the pass will not warn about unused function arguments.  \nExamples:\n\nunused.jsr:\n```lua\nfun test(arg1, arg2)\n    var foo = \"bar\"\n    print(arg1)\nend\n\n// pulsar will not warn for the unused `arg_` as its name ends with a trailing underscore\nfun stub(arg_)\n    raise NotImplementedException()\nend\n```\noutput:\n```\nAnalyzing unused.jsr...\nFile unused.jsr [line 1]:\nfun test(arg1, arg2)\n               ^~~~\nName 'arg2' declared but not used\nFile unused.jsr [line 2]:\n\n    var foo = \"bar\"\n        ^~~\nName 'foo' declared but not used\n```\n\n### Return check pass\nThis pass reports non-void functions that don't return a result on all possible execution paths. A\nfunction is considered non-void if it has at least one non-bare return (a return statement with an\nexpression).  \nThis pass can be disabled by passing the `-r, --no-check-returns` option.  \nExamples:\n\nreturn.jsr:\n```lua\nfun foo(x)\n    if !x\n        return false\n    end\n    print(x)\nend\n```\noutput:\n```\nAnalyzing return.jsr...\nFile return.jsr [line 1]:\nfun foo(x)\n    ^~~\nNon-void function 'foo' doesn't return a value on all execution paths\n```\n\n### Unreachable code pass\nThis pass checks for unreachable statements, for example statements that follow a `return` or a\n`raise` that is always executed.  \nThis pass can be disabled by passing the `-U, --no-unreachable` option.  \nExample:\n\nunreachable.jsr\n```lua\nfun foo(x)\n    return x\n    print(x)\nend\n\nfun bar(y)\n    try\n        y += 2\n    ensure\n        raise Exception()\n    end\n    return y\nend\n```\noutput:\n```\nAnalyzing unreachable.jsr...\nFile unreachable.jsr [line 3]:\n\n    print(x)\n    ^~~~~\nUnreachable statement. Previous statement breaks control unconditionally\nFile unreachable.jsr [line 12]:\n\n    return y\n    ^~~~~~\nUnreachable statement. Previous statement breaks control unconditionally\n```\n\n## Access checking pass\nThis pass checks for and enforces naming conventions for private attributes/methods and constant\nvariables. Specifically, an attribute/method starting with an underscore (`_`) is considered private\nto the current class and can't be accessed by anything but `this`. Variables are instead considered\nconstants if their names are composed only of capital letters and underscores. For constant\nattribute variables, we do not warn if they are assigned to in the constructor, as otherwise there\nwon't be a way to initialize them.  \nThis pass can be disabled by passing the `-A, --no-access-check` option.  \nExample:\n\naccess.jsr\n```lua\nvar PI = 3.141592\n\nclass Foo\n    fun new(bar)\n        this._bar = bar\n    end\n\n    fun getBar()\n        return this._bar\n    end\nend\n\nvar foo = Foo(\"bar\")\n\nprint(foo._bar)\nprint(foo.getBar())\n\nPI = 3.15\nprint(PI)\n```\noutput:\n```\nAnalyzing access.jsr...\nFile access.jsr [line 15]:\nprint(foo._bar)\n          ^~~~\nAccessing supposedly private attribute '_bar'\nFile access.jsr [line 18]:\nPI = 3.15\n^~\nAssigning to supposedly constant name PI\n```\n\n## How to use\n\nPulsar doesn't have any dependency (aside from the obvious one of **J\\***) so using it is as simple\nas cloning the repository:\n```bash\ngit clone https://github.com/bamless/pulsar.git\n```\nmoving in its directory:\n```bash\ncd pulsar\n```\nand executing `pulsar.jsr` with a list of **J\\*** files to check:\n```bash\njstar pulsar.jsr file1.jsr file2.jsr file3.jsr\n\n# Or more simply on unix-like systems\n./pulsar.jsr file1.jsr file2.jsr file3.jsr\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbamless%2Fpulsar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbamless%2Fpulsar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbamless%2Fpulsar/lists"}