Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

All notable changes to this project will be documented in this file.

## [Unreleased]
## [0.26.0] - 2026-03-02

### Added
- [Issue #208] - support `:gen-class :implements` ([PR-209])

### Fixed
- minor: update [glob library](https://www.npmjs.com/package/glob) ([PR-206])

## [0.25.0] - 2025-09-22

Expand Down Expand Up @@ -191,7 +197,8 @@ All notable changes to this project will be documented in this file.
### Added
- initial alpha release

[Unreleased]:https://github.com/oakmac/standard-clojure-style-js/compare/v0.25.0...HEAD
[Unreleased]:https://github.com/oakmac/standard-clojure-style-js/compare/v0.26.0...HEAD
[0.26.0]:https://github.com/oakmac/standard-clojure-style-js/releases/tag/v0.26.0
[0.25.0]:https://github.com/oakmac/standard-clojure-style-js/releases/tag/v0.25.0
[0.24.0]:https://github.com/oakmac/standard-clojure-style-js/releases/tag/v0.24.0
[0.23.0]:https://github.com/oakmac/standard-clojure-style-js/releases/tag/v0.23.0
Expand Down Expand Up @@ -270,6 +277,7 @@ All notable changes to this project will be documented in this file.
[Issue #189]:https://github.com/oakmac/standard-clojure-style-js/issues/189
[Issue #191]:https://github.com/oakmac/standard-clojure-style-js/issues/191
[Issue #203]:https://github.com/oakmac/standard-clojure-style-js/issues/203
[Issue #208]:https://github.com/oakmac/standard-clojure-style-js/issues/208

[commit #db857ff4]:https://github.com/oakmac/standard-clojure-style-js/commit/db857ff413f0a8625c0cd0c975684244d875705e

Expand Down Expand Up @@ -323,3 +331,5 @@ All notable changes to this project will be documented in this file.
[PR-190]:https://github.com/oakmac/standard-clojure-style-js/pull/190
[PR-192]:https://github.com/oakmac/standard-clojure-style-js/pull/192
[PR-204]:https://github.com/oakmac/standard-clojure-style-js/pull/204
[PR-206]:https://github.com/oakmac/standard-clojure-style-js/pull/206
[PR-209]:https://github.com/oakmac/standard-clojure-style-js/pull/209
50 changes: 48 additions & 2 deletions lib/standard-clojure-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -1415,6 +1415,11 @@
result.referClojure.rename.sort(compareFromSymbol)
}

// sort :gen-class :implements
if (result.genClass && isArray(result.genClass.implements)) {
result.genClass.implements.sort(compareSymbolsThenPlatform)
}

// sort :require-macros symbols
if (isArray(result.requireMacros)) {
result.requireMacros.sort(compareSymbolsThenPlatform)
Expand Down Expand Up @@ -1667,6 +1672,8 @@
let sectionToAttachEolCommentsTo = null
let nextTokenIsRequireDefaultSymbol = false
let numSymbolsInsideList = 0
let insideGenClassImplements = false
let genClassImplementsParenDepth = -1

while (continueParsingNsForm) {
const node = nodesArr[idx]
Expand Down Expand Up @@ -1732,6 +1739,12 @@
requireListParenNestingDepth = parenNestingDepth
} else if (insideImportForm && parenNestingDepth > importNodeParenNestingDepth) {
insideImportPackageList = true
} else if (insideGenClass && genClassToggle === 1 && genClassKeyStr === 'implements') {
insideGenClassImplements = true
genClassImplementsParenDepth = parenNestingDepth
if (!isArray(result.genClass.implements)) {
result.genClass.implements = []
}
}
} else if (isParenCloser(node)) {
parenNestingDepth = dec(parenNestingDepth)
Expand Down Expand Up @@ -1816,6 +1829,12 @@
collectRequireExcludeSymbols = false
requireExcludeSymbolParenDepth = -1
}
if (insideGenClassImplements && parenNestingDepth < genClassImplementsParenDepth) {
insideGenClassImplements = false
genClassImplementsParenDepth = -1
genClassToggle = 0 // back to looking for a :gen-class key
genClassValueLineNo = lineNo
}

requireMacrosReferNodeIdx = -1
requireMacrosRenameIdx = -1
Expand Down Expand Up @@ -2445,6 +2464,15 @@
} else {
stackPush(result.importsObj[importPackageListFirstToken].classes, node.text)
}

// collect gen-class :implements symbols
} else if (insideGenClass && insideGenClassImplements && idx > genClassNodeIdx && isTokenNode2 && isTextNode && genClassToggle === 1 && genClassKeyStr === 'implements') {
const symbolObj = { symbol: node.text }
if (insideReaderConditional && currentReaderConditionalPlatform) {
symbolObj.platform = currentReaderConditionalPlatform
}
stackPush(result.genClass.implements, symbolObj)

// we are on the :gen-class node
} else if (insideGenClass && idx === genClassNodeIdx) {
result.genClass = {}
Expand Down Expand Up @@ -2506,7 +2534,8 @@
// FIXME: throw here? this is almost certainly an error in the source
}
}
// FIXME: we need to handle :implements, :constructors, :methods, :exposes, :exposes-methods, here

// FIXME: we need to handle :constructors, :methods, :exposes, :exposes-methods, here

// throw an error if we encounter :use
} else if (insideNsForm && isTokenNode2 && parenNestingDepth >= 1 && isUseNode(node)) {
Expand Down Expand Up @@ -3424,7 +3453,24 @@

outTxt = strConcat(outTxt, indentationStr2)
outTxt = strConcat3(outTxt, ':', genClassKey)
outTxt = strConcat3(outTxt, ' ', genClassValue.value)

if (genClassKey === 'implements') {
const numInterfaces = arraySize(genClassValue)
let interfaceIdx = 0
while (interfaceIdx < numInterfaces) {
if (interfaceIdx === 0) {
outTxt = strConcat3(outTxt, ' [', genClassValue[interfaceIdx].symbol)
} else {
outTxt = strConcat3(outTxt, ' ', genClassValue[interfaceIdx].symbol)
}
interfaceIdx = interfaceIdx + 1
}
if (numInterfaces > 0) {
outTxt = strConcat(outTxt, ']')
}
} else {
outTxt = strConcat3(outTxt, ' ', genClassValue.value)
}

if (isStringWithChars(genClassValue.commentAfter)) {
commentAfterGenClass = genClassValue.commentAfter
Expand Down
67 changes: 67 additions & 0 deletions test_format/ns.eno
Original file line number Diff line number Diff line change
Expand Up @@ -2019,3 +2019,70 @@
["bar-foo" :as bf :default Barfoo]
["foo-bar" :as fb :default Foobar]))
--Expected

# GitHub Issue #208 - basic :gen-class :implements

--Input
(ns example-ns
(:gen-class
:implements [com.amazonaws.services.lambda.runtime.RequestStreamHandler]))
--Input

--Expected
(ns example-ns
(:gen-class
:implements [com.amazonaws.services.lambda.runtime.RequestStreamHandler]))
--Expected

# GitHub Issue #208 - :gen-class :implements with sorting

--Input
(ns com.example.my-app
"complex gen-class"
;; aaa
;; bbb
(:gen-class ;; ccc
:implements [zap.zip.RockSock foo.bar.BizBang] ;; uuu

;; fff
:extends java.lang.RuntimeException ;; ggg
:impl-ns iii
:post-init jjj
:main true
:state state2
:prefix "zzz-"

;; ddd
:name name2 ;; eee

:factory fff
:load-impl-ns false ;; hhh
:init init2)


(:require [aaa.bbb :as ab])
)
--Input

--Expected
(ns com.example.my-app
"complex gen-class"
(:require
[aaa.bbb :as ab])
;; aaa
;; bbb
(:gen-class ;; ccc
;; ddd
:name name2 ;; eee
;; fff
:extends java.lang.RuntimeException ;; ggg
:implements [foo.bar.BizBang zap.zip.RockSock] ;; uuu
:init init2
:post-init jjj
:main true
:factory fff
:state state2
:prefix "zzz-"
:impl-ns iii
:load-impl-ns false)) ;; hhh
--Expected
21 changes: 21 additions & 0 deletions test_parse_ns/parse_ns.eno
Original file line number Diff line number Diff line change
Expand Up @@ -3290,3 +3290,24 @@
]
}
--Expected

# GitHub Issue #208 - implements

--Input
(ns com.example.my-app
(:gen-class
:implements [zap.zip.RockSock foo.bar.BizBang]))
--Input

--Expected
{
"nsSymbol": "com.example.my-app",
"genClass": {
"isEmpty": false,
"implements": [
{"symbol": "foo.bar.BizBang"},
{"symbol": "zap.zip.RockSock"}
]
}
}
--Expected