@booklib/core 2.0.0
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.
- package/.cursor/rules/booklib-standards.mdc +40 -0
- package/.gemini/context.md +372 -0
- package/AGENTS.md +166 -0
- package/CHANGELOG.md +226 -0
- package/CLAUDE.md +81 -0
- package/CODE_OF_CONDUCT.md +31 -0
- package/CONTRIBUTING.md +304 -0
- package/LICENSE +21 -0
- package/PLAN.md +28 -0
- package/README.ja.md +198 -0
- package/README.ko.md +198 -0
- package/README.md +503 -0
- package/README.pt-BR.md +198 -0
- package/README.uk.md +241 -0
- package/README.zh-CN.md +198 -0
- package/SECURITY.md +9 -0
- package/agents/architecture-reviewer.md +136 -0
- package/agents/booklib-reviewer.md +90 -0
- package/agents/data-reviewer.md +107 -0
- package/agents/jvm-reviewer.md +146 -0
- package/agents/python-reviewer.md +128 -0
- package/agents/rust-reviewer.md +115 -0
- package/agents/ts-reviewer.md +110 -0
- package/agents/ui-reviewer.md +117 -0
- package/assets/logo.svg +36 -0
- package/bin/booklib-mcp.js +304 -0
- package/bin/booklib.js +1705 -0
- package/bin/skills.cjs +1292 -0
- package/booklib-router.mdc +36 -0
- package/booklib.config.json +19 -0
- package/commands/animation-at-work.md +10 -0
- package/commands/clean-code-reviewer.md +10 -0
- package/commands/data-intensive-patterns.md +10 -0
- package/commands/data-pipelines.md +10 -0
- package/commands/design-patterns.md +10 -0
- package/commands/domain-driven-design.md +10 -0
- package/commands/effective-java.md +10 -0
- package/commands/effective-kotlin.md +10 -0
- package/commands/effective-python.md +10 -0
- package/commands/effective-typescript.md +10 -0
- package/commands/kotlin-in-action.md +10 -0
- package/commands/lean-startup.md +10 -0
- package/commands/microservices-patterns.md +10 -0
- package/commands/programming-with-rust.md +10 -0
- package/commands/refactoring-ui.md +10 -0
- package/commands/rust-in-action.md +10 -0
- package/commands/skill-router.md +10 -0
- package/commands/spring-boot-in-action.md +10 -0
- package/commands/storytelling-with-data.md +10 -0
- package/commands/system-design-interview.md +10 -0
- package/commands/using-asyncio-python.md +10 -0
- package/commands/web-scraping-python.md +10 -0
- package/community/registry.json +1616 -0
- package/hooks/hooks.json +23 -0
- package/hooks/posttooluse-capture.mjs +67 -0
- package/hooks/suggest.js +153 -0
- package/lib/agent-behaviors.js +40 -0
- package/lib/agent-detector.js +96 -0
- package/lib/config-loader.js +39 -0
- package/lib/conflict-resolver.js +148 -0
- package/lib/context-builder.js +574 -0
- package/lib/discovery-engine.js +298 -0
- package/lib/doctor/hook-installer.js +83 -0
- package/lib/doctor/usage-tracker.js +87 -0
- package/lib/engine/ai-features.js +253 -0
- package/lib/engine/auditor.js +103 -0
- package/lib/engine/bm25-index.js +178 -0
- package/lib/engine/capture.js +120 -0
- package/lib/engine/corrections.js +198 -0
- package/lib/engine/doctor.js +195 -0
- package/lib/engine/graph-injector.js +137 -0
- package/lib/engine/graph.js +161 -0
- package/lib/engine/handoff.js +405 -0
- package/lib/engine/indexer.js +242 -0
- package/lib/engine/parser.js +53 -0
- package/lib/engine/query-expander.js +42 -0
- package/lib/engine/reranker.js +40 -0
- package/lib/engine/rrf.js +59 -0
- package/lib/engine/scanner.js +151 -0
- package/lib/engine/searcher.js +139 -0
- package/lib/engine/session-coordinator.js +306 -0
- package/lib/engine/session-manager.js +429 -0
- package/lib/engine/synthesizer.js +70 -0
- package/lib/installer.js +70 -0
- package/lib/instinct-block.js +33 -0
- package/lib/mcp-config-writer.js +88 -0
- package/lib/paths.js +57 -0
- package/lib/profiles/design.md +19 -0
- package/lib/profiles/general.md +16 -0
- package/lib/profiles/research-analysis.md +22 -0
- package/lib/profiles/software-development.md +23 -0
- package/lib/profiles/writing-content.md +19 -0
- package/lib/project-initializer.js +916 -0
- package/lib/registry/skills.js +102 -0
- package/lib/registry-searcher.js +99 -0
- package/lib/rules/rules-manager.js +169 -0
- package/lib/skill-fetcher.js +333 -0
- package/lib/well-known-builder.js +70 -0
- package/lib/wizard/index.js +404 -0
- package/lib/wizard/integration-detector.js +41 -0
- package/lib/wizard/project-detector.js +100 -0
- package/lib/wizard/prompt.js +156 -0
- package/lib/wizard/registry-embeddings.js +107 -0
- package/lib/wizard/skill-recommender.js +69 -0
- package/llms-full.txt +254 -0
- package/llms.txt +70 -0
- package/package.json +45 -0
- package/research-reports/2026-04-01-current-architecture.md +160 -0
- package/research-reports/IDEAS.md +93 -0
- package/rules/common/clean-code.md +42 -0
- package/rules/java/effective-java.md +42 -0
- package/rules/kotlin/effective-kotlin.md +37 -0
- package/rules/python/effective-python.md +38 -0
- package/rules/rust/rust.md +37 -0
- package/rules/typescript/effective-typescript.md +42 -0
- package/scripts/gen-llms-full.mjs +36 -0
- package/scripts/gen-og.mjs +142 -0
- package/scripts/validate-frontmatter.js +25 -0
- package/skills/animation-at-work/SKILL.md +270 -0
- package/skills/animation-at-work/assets/example_asset.txt +1 -0
- package/skills/animation-at-work/evals/evals.json +44 -0
- package/skills/animation-at-work/evals/results.json +13 -0
- package/skills/animation-at-work/examples/after.md +64 -0
- package/skills/animation-at-work/examples/before.md +35 -0
- package/skills/animation-at-work/references/api_reference.md +369 -0
- package/skills/animation-at-work/references/review-checklist.md +79 -0
- package/skills/animation-at-work/scripts/audit_animations.py +295 -0
- package/skills/animation-at-work/scripts/example.py +1 -0
- package/skills/clean-code-reviewer/SKILL.md +444 -0
- package/skills/clean-code-reviewer/audit.json +35 -0
- package/skills/clean-code-reviewer/evals/evals.json +185 -0
- package/skills/clean-code-reviewer/evals/results.json +13 -0
- package/skills/clean-code-reviewer/examples/after.md +48 -0
- package/skills/clean-code-reviewer/examples/before.md +33 -0
- package/skills/clean-code-reviewer/references/api_reference.md +158 -0
- package/skills/clean-code-reviewer/references/practices-catalog.md +282 -0
- package/skills/clean-code-reviewer/references/review-checklist.md +254 -0
- package/skills/clean-code-reviewer/scripts/pre-review.py +206 -0
- package/skills/data-intensive-patterns/SKILL.md +267 -0
- package/skills/data-intensive-patterns/assets/example_asset.txt +1 -0
- package/skills/data-intensive-patterns/evals/evals.json +54 -0
- package/skills/data-intensive-patterns/evals/results.json +13 -0
- package/skills/data-intensive-patterns/examples/after.md +61 -0
- package/skills/data-intensive-patterns/examples/before.md +38 -0
- package/skills/data-intensive-patterns/references/api_reference.md +34 -0
- package/skills/data-intensive-patterns/references/patterns-catalog.md +551 -0
- package/skills/data-intensive-patterns/references/review-checklist.md +193 -0
- package/skills/data-intensive-patterns/scripts/adr.py +213 -0
- package/skills/data-intensive-patterns/scripts/example.py +1 -0
- package/skills/data-pipelines/SKILL.md +259 -0
- package/skills/data-pipelines/assets/example_asset.txt +1 -0
- package/skills/data-pipelines/evals/evals.json +45 -0
- package/skills/data-pipelines/evals/results.json +13 -0
- package/skills/data-pipelines/examples/after.md +97 -0
- package/skills/data-pipelines/examples/before.md +37 -0
- package/skills/data-pipelines/references/api_reference.md +301 -0
- package/skills/data-pipelines/references/review-checklist.md +181 -0
- package/skills/data-pipelines/scripts/example.py +1 -0
- package/skills/data-pipelines/scripts/new_pipeline.py +444 -0
- package/skills/design-patterns/SKILL.md +271 -0
- package/skills/design-patterns/assets/example_asset.txt +1 -0
- package/skills/design-patterns/evals/evals.json +46 -0
- package/skills/design-patterns/evals/results.json +13 -0
- package/skills/design-patterns/examples/after.md +52 -0
- package/skills/design-patterns/examples/before.md +29 -0
- package/skills/design-patterns/references/api_reference.md +1 -0
- package/skills/design-patterns/references/patterns-catalog.md +726 -0
- package/skills/design-patterns/references/review-checklist.md +173 -0
- package/skills/design-patterns/scripts/example.py +1 -0
- package/skills/design-patterns/scripts/scaffold.py +807 -0
- package/skills/domain-driven-design/SKILL.md +142 -0
- package/skills/domain-driven-design/assets/example_asset.txt +1 -0
- package/skills/domain-driven-design/evals/evals.json +48 -0
- package/skills/domain-driven-design/evals/results.json +13 -0
- package/skills/domain-driven-design/examples/after.md +80 -0
- package/skills/domain-driven-design/examples/before.md +43 -0
- package/skills/domain-driven-design/references/api_reference.md +1 -0
- package/skills/domain-driven-design/references/patterns-catalog.md +545 -0
- package/skills/domain-driven-design/references/review-checklist.md +158 -0
- package/skills/domain-driven-design/scripts/example.py +1 -0
- package/skills/domain-driven-design/scripts/scaffold.py +421 -0
- package/skills/effective-java/SKILL.md +227 -0
- package/skills/effective-java/assets/example_asset.txt +1 -0
- package/skills/effective-java/evals/evals.json +46 -0
- package/skills/effective-java/evals/results.json +13 -0
- package/skills/effective-java/examples/after.md +83 -0
- package/skills/effective-java/examples/before.md +37 -0
- package/skills/effective-java/references/api_reference.md +1 -0
- package/skills/effective-java/references/items-catalog.md +955 -0
- package/skills/effective-java/references/review-checklist.md +216 -0
- package/skills/effective-java/scripts/checkstyle_setup.py +211 -0
- package/skills/effective-java/scripts/example.py +1 -0
- package/skills/effective-kotlin/SKILL.md +271 -0
- package/skills/effective-kotlin/assets/example_asset.txt +1 -0
- package/skills/effective-kotlin/audit.json +29 -0
- package/skills/effective-kotlin/evals/evals.json +45 -0
- package/skills/effective-kotlin/evals/results.json +13 -0
- package/skills/effective-kotlin/examples/after.md +36 -0
- package/skills/effective-kotlin/examples/before.md +38 -0
- package/skills/effective-kotlin/references/api_reference.md +1 -0
- package/skills/effective-kotlin/references/practices-catalog.md +1228 -0
- package/skills/effective-kotlin/references/review-checklist.md +126 -0
- package/skills/effective-kotlin/scripts/example.py +1 -0
- package/skills/effective-python/SKILL.md +441 -0
- package/skills/effective-python/evals/evals.json +44 -0
- package/skills/effective-python/evals/results.json +13 -0
- package/skills/effective-python/examples/after.md +56 -0
- package/skills/effective-python/examples/before.md +40 -0
- package/skills/effective-python/ref-01-pythonic-thinking.md +202 -0
- package/skills/effective-python/ref-02-lists-and-dicts.md +146 -0
- package/skills/effective-python/ref-03-functions.md +186 -0
- package/skills/effective-python/ref-04-comprehensions-generators.md +211 -0
- package/skills/effective-python/ref-05-classes-interfaces.md +188 -0
- package/skills/effective-python/ref-06-metaclasses-attributes.md +209 -0
- package/skills/effective-python/ref-07-concurrency.md +213 -0
- package/skills/effective-python/ref-08-robustness-performance.md +248 -0
- package/skills/effective-python/ref-09-testing-debugging.md +253 -0
- package/skills/effective-python/ref-10-collaboration.md +175 -0
- package/skills/effective-python/references/api_reference.md +218 -0
- package/skills/effective-python/references/practices-catalog.md +483 -0
- package/skills/effective-python/references/review-checklist.md +190 -0
- package/skills/effective-python/scripts/lint.py +173 -0
- package/skills/effective-typescript/SKILL.md +262 -0
- package/skills/effective-typescript/audit.json +29 -0
- package/skills/effective-typescript/evals/evals.json +37 -0
- package/skills/effective-typescript/evals/results.json +13 -0
- package/skills/effective-typescript/examples/after.md +70 -0
- package/skills/effective-typescript/examples/before.md +47 -0
- package/skills/effective-typescript/references/api_reference.md +118 -0
- package/skills/effective-typescript/references/practices-catalog.md +371 -0
- package/skills/effective-typescript/scripts/review.py +169 -0
- package/skills/kotlin-in-action/SKILL.md +261 -0
- package/skills/kotlin-in-action/assets/example_asset.txt +1 -0
- package/skills/kotlin-in-action/evals/evals.json +43 -0
- package/skills/kotlin-in-action/evals/results.json +13 -0
- package/skills/kotlin-in-action/examples/after.md +53 -0
- package/skills/kotlin-in-action/examples/before.md +39 -0
- package/skills/kotlin-in-action/references/api_reference.md +1 -0
- package/skills/kotlin-in-action/references/practices-catalog.md +436 -0
- package/skills/kotlin-in-action/references/review-checklist.md +204 -0
- package/skills/kotlin-in-action/scripts/example.py +1 -0
- package/skills/kotlin-in-action/scripts/setup_detekt.py +224 -0
- package/skills/lean-startup/SKILL.md +160 -0
- package/skills/lean-startup/assets/example_asset.txt +1 -0
- package/skills/lean-startup/evals/evals.json +43 -0
- package/skills/lean-startup/evals/results.json +13 -0
- package/skills/lean-startup/examples/after.md +80 -0
- package/skills/lean-startup/examples/before.md +34 -0
- package/skills/lean-startup/references/api_reference.md +319 -0
- package/skills/lean-startup/references/review-checklist.md +137 -0
- package/skills/lean-startup/scripts/example.py +1 -0
- package/skills/lean-startup/scripts/new_experiment.py +286 -0
- package/skills/microservices-patterns/SKILL.md +384 -0
- package/skills/microservices-patterns/evals/evals.json +45 -0
- package/skills/microservices-patterns/evals/results.json +13 -0
- package/skills/microservices-patterns/examples/after.md +69 -0
- package/skills/microservices-patterns/examples/before.md +40 -0
- package/skills/microservices-patterns/references/patterns-catalog.md +391 -0
- package/skills/microservices-patterns/references/review-checklist.md +169 -0
- package/skills/microservices-patterns/scripts/new_service.py +583 -0
- package/skills/programming-with-rust/SKILL.md +209 -0
- package/skills/programming-with-rust/evals/evals.json +37 -0
- package/skills/programming-with-rust/evals/results.json +13 -0
- package/skills/programming-with-rust/examples/after.md +107 -0
- package/skills/programming-with-rust/examples/before.md +59 -0
- package/skills/programming-with-rust/references/api_reference.md +152 -0
- package/skills/programming-with-rust/references/practices-catalog.md +335 -0
- package/skills/programming-with-rust/scripts/review.py +142 -0
- package/skills/refactoring-ui/SKILL.md +362 -0
- package/skills/refactoring-ui/assets/example_asset.txt +1 -0
- package/skills/refactoring-ui/evals/evals.json +45 -0
- package/skills/refactoring-ui/evals/results.json +13 -0
- package/skills/refactoring-ui/examples/after.md +85 -0
- package/skills/refactoring-ui/examples/before.md +58 -0
- package/skills/refactoring-ui/references/api_reference.md +355 -0
- package/skills/refactoring-ui/references/review-checklist.md +114 -0
- package/skills/refactoring-ui/scripts/audit_css.py +250 -0
- package/skills/refactoring-ui/scripts/example.py +1 -0
- package/skills/rust-in-action/SKILL.md +350 -0
- package/skills/rust-in-action/evals/evals.json +38 -0
- package/skills/rust-in-action/evals/results.json +13 -0
- package/skills/rust-in-action/examples/after.md +156 -0
- package/skills/rust-in-action/examples/before.md +56 -0
- package/skills/rust-in-action/references/practices-catalog.md +346 -0
- package/skills/rust-in-action/scripts/review.py +147 -0
- package/skills/skill-router/SKILL.md +186 -0
- package/skills/skill-router/evals/evals.json +38 -0
- package/skills/skill-router/evals/results.json +13 -0
- package/skills/skill-router/examples/after.md +63 -0
- package/skills/skill-router/examples/before.md +39 -0
- package/skills/skill-router/references/api_reference.md +24 -0
- package/skills/skill-router/references/routing-heuristics.md +89 -0
- package/skills/skill-router/references/skill-catalog.md +174 -0
- package/skills/skill-router/scripts/route.py +266 -0
- package/skills/spring-boot-in-action/SKILL.md +340 -0
- package/skills/spring-boot-in-action/evals/evals.json +39 -0
- package/skills/spring-boot-in-action/evals/results.json +13 -0
- package/skills/spring-boot-in-action/examples/after.md +185 -0
- package/skills/spring-boot-in-action/examples/before.md +84 -0
- package/skills/spring-boot-in-action/references/practices-catalog.md +403 -0
- package/skills/spring-boot-in-action/scripts/review.py +184 -0
- package/skills/storytelling-with-data/SKILL.md +241 -0
- package/skills/storytelling-with-data/assets/example_asset.txt +1 -0
- package/skills/storytelling-with-data/evals/evals.json +47 -0
- package/skills/storytelling-with-data/evals/results.json +13 -0
- package/skills/storytelling-with-data/examples/after.md +50 -0
- package/skills/storytelling-with-data/examples/before.md +33 -0
- package/skills/storytelling-with-data/references/api_reference.md +379 -0
- package/skills/storytelling-with-data/references/review-checklist.md +111 -0
- package/skills/storytelling-with-data/scripts/chart_review.py +301 -0
- package/skills/storytelling-with-data/scripts/example.py +1 -0
- package/skills/system-design-interview/SKILL.md +233 -0
- package/skills/system-design-interview/assets/example_asset.txt +1 -0
- package/skills/system-design-interview/evals/evals.json +46 -0
- package/skills/system-design-interview/evals/results.json +13 -0
- package/skills/system-design-interview/examples/after.md +94 -0
- package/skills/system-design-interview/examples/before.md +27 -0
- package/skills/system-design-interview/references/api_reference.md +582 -0
- package/skills/system-design-interview/references/review-checklist.md +201 -0
- package/skills/system-design-interview/scripts/example.py +1 -0
- package/skills/system-design-interview/scripts/new_design.py +421 -0
- package/skills/using-asyncio-python/SKILL.md +290 -0
- package/skills/using-asyncio-python/assets/example_asset.txt +1 -0
- package/skills/using-asyncio-python/evals/evals.json +43 -0
- package/skills/using-asyncio-python/evals/results.json +13 -0
- package/skills/using-asyncio-python/examples/after.md +68 -0
- package/skills/using-asyncio-python/examples/before.md +39 -0
- package/skills/using-asyncio-python/references/api_reference.md +267 -0
- package/skills/using-asyncio-python/references/review-checklist.md +149 -0
- package/skills/using-asyncio-python/scripts/check_blocking.py +270 -0
- package/skills/using-asyncio-python/scripts/example.py +1 -0
- package/skills/web-scraping-python/SKILL.md +280 -0
- package/skills/web-scraping-python/assets/example_asset.txt +1 -0
- package/skills/web-scraping-python/evals/evals.json +46 -0
- package/skills/web-scraping-python/evals/results.json +13 -0
- package/skills/web-scraping-python/examples/after.md +109 -0
- package/skills/web-scraping-python/examples/before.md +40 -0
- package/skills/web-scraping-python/references/api_reference.md +393 -0
- package/skills/web-scraping-python/references/review-checklist.md +163 -0
- package/skills/web-scraping-python/scripts/example.py +1 -0
- package/skills/web-scraping-python/scripts/new_scraper.py +231 -0
- package/skills/writing-plans/audit.json +34 -0
- package/tests/agent-detector.test.js +83 -0
- package/tests/corrections.test.js +245 -0
- package/tests/doctor/hook-installer.test.js +72 -0
- package/tests/doctor/usage-tracker.test.js +140 -0
- package/tests/engine/benchmark-eval.test.js +31 -0
- package/tests/engine/bm25-index.test.js +85 -0
- package/tests/engine/capture-command.test.js +35 -0
- package/tests/engine/capture.test.js +17 -0
- package/tests/engine/graph-augmented-search.test.js +107 -0
- package/tests/engine/graph-injector.test.js +44 -0
- package/tests/engine/graph.test.js +216 -0
- package/tests/engine/hybrid-searcher.test.js +74 -0
- package/tests/engine/indexer-bm25.test.js +37 -0
- package/tests/engine/mcp-tools.test.js +73 -0
- package/tests/engine/project-initializer-mcp.test.js +99 -0
- package/tests/engine/query-expander.test.js +36 -0
- package/tests/engine/reranker.test.js +51 -0
- package/tests/engine/rrf.test.js +49 -0
- package/tests/engine/srag-prefix.test.js +47 -0
- package/tests/instinct-block.test.js +23 -0
- package/tests/mcp-config-writer.test.js +60 -0
- package/tests/project-initializer-new-agents.test.js +48 -0
- package/tests/rules/rules-manager.test.js +230 -0
- package/tests/well-known-builder.test.js +40 -0
- package/tests/wizard/integration-detector.test.js +31 -0
- package/tests/wizard/project-detector.test.js +51 -0
- package/tests/wizard/prompt-session.test.js +61 -0
- package/tests/wizard/prompt.test.js +16 -0
- package/tests/wizard/registry-embeddings.test.js +35 -0
- package/tests/wizard/skill-recommender.test.js +34 -0
- package/tests/wizard/slot-count.test.js +25 -0
- package/vercel.json +21 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Effective Java Code Review Checklist
|
|
2
|
+
|
|
3
|
+
Use this checklist when reviewing Java code. Work through each section and flag any
|
|
4
|
+
violations. Not every section applies to every review — skip sections that aren't
|
|
5
|
+
relevant to the code under review.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Object Creation
|
|
10
|
+
|
|
11
|
+
- [ ] Static factory methods used where beneficial (named construction, caching, return subtypes)
|
|
12
|
+
- [ ] Builder pattern used for classes with many optional parameters
|
|
13
|
+
- [ ] Singleton enforcement is correct (enum type or private constructor with static field)
|
|
14
|
+
- [ ] Utility classes have private constructor to prevent instantiation
|
|
15
|
+
- [ ] Dependencies are injected, not hardwired to concrete implementations
|
|
16
|
+
- [ ] No unnecessary object creation (cached patterns, primitive vs boxed in loops)
|
|
17
|
+
- [ ] Obsolete object references are nulled out (custom collections, caches, listeners)
|
|
18
|
+
- [ ] try-with-resources used for all AutoCloseable objects
|
|
19
|
+
- [ ] No finalizers or cleaners (except as safety nets for native resources)
|
|
20
|
+
|
|
21
|
+
**Red flags**: Telescoping constructors with 4+ parameters. `new String("literal")`.
|
|
22
|
+
`Long sum = 0L` in a loop. Resources closed in finally blocks instead of
|
|
23
|
+
try-with-resources. Finalizer or cleaner used for non-native resource cleanup.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 2. Methods Common to All Objects
|
|
28
|
+
|
|
29
|
+
- [ ] `equals` override obeys the contract (reflexive, symmetric, transitive, consistent)
|
|
30
|
+
- [ ] `hashCode` is overridden whenever `equals` is overridden
|
|
31
|
+
- [ ] `toString` provides useful diagnostic information
|
|
32
|
+
- [ ] `clone` is avoided in favor of copy constructors or copy factories
|
|
33
|
+
- [ ] `Comparable` is implemented where natural ordering exists
|
|
34
|
+
- [ ] Comparators don't use subtraction (overflow risk)
|
|
35
|
+
|
|
36
|
+
**Red flags**: `equals` that breaks symmetry (subclass vs superclass). Missing `hashCode`
|
|
37
|
+
override causing HashMap failures. `Cloneable` implemented on new classes. Comparator
|
|
38
|
+
using `return o1.val - o2.val` (integer overflow).
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 3. Class Design
|
|
43
|
+
|
|
44
|
+
- [ ] Classes and members have minimal accessibility (private > package-private > protected > public)
|
|
45
|
+
- [ ] Instance fields are never public (use accessors)
|
|
46
|
+
- [ ] Classes are immutable where possible (final fields, no setters, final class or private constructor)
|
|
47
|
+
- [ ] Composition is used instead of inheritance across package boundaries
|
|
48
|
+
- [ ] Classes designed for inheritance document self-use of overridable methods
|
|
49
|
+
- [ ] Classes not designed for inheritance are final or have private constructors
|
|
50
|
+
- [ ] Interfaces are used to define types, not for constants
|
|
51
|
+
- [ ] Tagged classes are refactored into class hierarchies
|
|
52
|
+
- [ ] Inner classes are static unless they need an enclosing instance reference
|
|
53
|
+
- [ ] One top-level class per source file
|
|
54
|
+
|
|
55
|
+
**Red flags**: Public mutable fields. Concrete class extended across package boundary
|
|
56
|
+
without documentation of overridable method self-use. Non-static inner class in a
|
|
57
|
+
long-lived object (hidden reference causes memory leak). Constant interface
|
|
58
|
+
(`interface Constants { int FOO = 1; }`).
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 4. Generics
|
|
63
|
+
|
|
64
|
+
- [ ] No raw types anywhere in the codebase
|
|
65
|
+
- [ ] All unchecked warnings are eliminated or suppressed with justification
|
|
66
|
+
- [ ] Lists preferred over arrays for generic collections
|
|
67
|
+
- [ ] Types and methods are generic where appropriate
|
|
68
|
+
- [ ] Bounded wildcards used per PECS (Producer-Extends, Consumer-Super)
|
|
69
|
+
- [ ] `@SafeVarargs` used correctly on generic varargs methods
|
|
70
|
+
- [ ] No wildcards on return types
|
|
71
|
+
|
|
72
|
+
**Red flags**: `List` instead of `List<String>`. `@SuppressWarnings("unchecked")` on a
|
|
73
|
+
large scope without comment. `E[]` used where `List<E>` would be safer. Missing
|
|
74
|
+
wildcards on API parameters that accept subtypes.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 5. Enums and Annotations
|
|
79
|
+
|
|
80
|
+
- [ ] Enums used instead of `int` or `String` constants
|
|
81
|
+
- [ ] Enum values don't derive from `ordinal()` — instance fields used instead
|
|
82
|
+
- [ ] `EnumSet` used instead of bit fields
|
|
83
|
+
- [ ] `EnumMap` used instead of ordinal-indexed arrays
|
|
84
|
+
- [ ] `@Override` annotation present on all overriding methods
|
|
85
|
+
- [ ] Annotations used instead of naming patterns
|
|
86
|
+
|
|
87
|
+
**Red flags**: `public static final int SEASON_WINTER = 0`. Calling `ordinal()` to
|
|
88
|
+
derive a value. `int` flags combined with bitwise OR instead of `EnumSet`. Array
|
|
89
|
+
indexed by `enum.ordinal()`.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 6. Lambdas and Streams
|
|
94
|
+
|
|
95
|
+
- [ ] Lambdas used instead of anonymous classes for functional interfaces
|
|
96
|
+
- [ ] Method references used where clearer than lambdas
|
|
97
|
+
- [ ] Standard functional interfaces from `java.util.function` used before custom ones
|
|
98
|
+
- [ ] Streams used judiciously (not forced where loops are clearer)
|
|
99
|
+
- [ ] Stream operations are side-effect-free (no mutation in `forEach` used for computation)
|
|
100
|
+
- [ ] `Collection` returned from APIs instead of `Stream`
|
|
101
|
+
- [ ] Parallel streams used only with appropriate data structures and verified speedup
|
|
102
|
+
|
|
103
|
+
**Red flags**: Long, complex lambdas (should be extracted to methods). `forEach` used
|
|
104
|
+
for computation instead of collect/reduce. `Stream.parallel()` on `LinkedList` or
|
|
105
|
+
`Stream.iterate`. Stream pipeline with side effects on shared mutable state.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 7. Method Design
|
|
110
|
+
|
|
111
|
+
- [ ] Parameters validated at method entry (`Objects.requireNonNull`, bounds checks)
|
|
112
|
+
- [ ] Defensive copies made of mutable input parameters (copy before validation)
|
|
113
|
+
- [ ] Method signatures have ≤4 parameters (or use helper classes / Builder)
|
|
114
|
+
- [ ] No confusing overloads (same number of parameters with different behavior)
|
|
115
|
+
- [ ] Varargs methods require at least one argument where needed
|
|
116
|
+
- [ ] Empty collections/arrays returned instead of null
|
|
117
|
+
- [ ] `Optional` used appropriately for absent return values (not for fields/parameters/collections)
|
|
118
|
+
- [ ] All exported API elements have doc comments
|
|
119
|
+
|
|
120
|
+
**Red flags**: Missing null check that leads to NPE deep in call stack. Mutable
|
|
121
|
+
`Date`/`Calendar` parameter stored directly without copy. Method returning `null`
|
|
122
|
+
instead of `Collections.emptyList()`. `Optional.get()` without presence check.
|
|
123
|
+
Overloaded methods with same arity causing dispatch surprises.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 8. General Programming
|
|
128
|
+
|
|
129
|
+
- [ ] Local variables declared at point of first use with minimal scope
|
|
130
|
+
- [ ] For-each loops used wherever applicable
|
|
131
|
+
- [ ] Standard library methods used instead of hand-rolled equivalents
|
|
132
|
+
- [ ] `BigDecimal` or `int`/`long` used for monetary calculations (not `float`/`double`)
|
|
133
|
+
- [ ] Primitive types preferred over boxed primitives
|
|
134
|
+
- [ ] Strings not used as substitutes for other types (enums, aggregates, capabilities)
|
|
135
|
+
- [ ] `StringBuilder` used for string concatenation in loops
|
|
136
|
+
- [ ] Objects referred to by interface types where appropriate
|
|
137
|
+
- [ ] Reflection avoided except for class instantiation via interfaces
|
|
138
|
+
- [ ] Naming conventions followed (camelCase methods, UPPER_SNAKE constants, etc.)
|
|
139
|
+
|
|
140
|
+
**Red flags**: `double` used for currency. `String` concatenation with `+` inside a loop
|
|
141
|
+
building large output. `==` applied to boxed primitives. Hand-rolled sorting or data
|
|
142
|
+
structure instead of using `java.util` classes. Variable declared far from use with
|
|
143
|
+
wide scope.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 9. Exceptions
|
|
148
|
+
|
|
149
|
+
- [ ] Exceptions used only for exceptional conditions (not control flow)
|
|
150
|
+
- [ ] Checked exceptions for recoverable conditions, runtime for programming errors
|
|
151
|
+
- [ ] Unnecessary checked exceptions eliminated (consider Optional or method splitting)
|
|
152
|
+
- [ ] Standard exceptions reused (`IllegalArgumentException`, `NullPointerException`, etc.)
|
|
153
|
+
- [ ] Exceptions translated at abstraction boundaries (with chaining)
|
|
154
|
+
- [ ] All exceptions documented with `@throws`
|
|
155
|
+
- [ ] Exception detail messages include failure-capture information
|
|
156
|
+
- [ ] Methods are failure-atomic (object state unchanged on failure)
|
|
157
|
+
- [ ] No empty catch blocks (if intentionally ignored, document why and use `ignored` variable name)
|
|
158
|
+
|
|
159
|
+
**Red flags**: `try { ... } catch (Exception e) { }` (swallowed exception). Exception
|
|
160
|
+
used for flow control (`try { array[i++] } catch (AIOOBE)`). Method declares
|
|
161
|
+
`throws Exception`. Low-level `SQLException` propagated through business logic instead
|
|
162
|
+
of translated.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 10. Concurrency
|
|
167
|
+
|
|
168
|
+
- [ ] Shared mutable data is properly synchronized or volatile
|
|
169
|
+
- [ ] Minimal work done inside synchronized regions
|
|
170
|
+
- [ ] No alien method calls within synchronized blocks
|
|
171
|
+
- [ ] `ExecutorService` used instead of raw `Thread` management
|
|
172
|
+
- [ ] `java.util.concurrent` utilities preferred over `wait`/`notify`
|
|
173
|
+
- [ ] Thread safety level documented on every class
|
|
174
|
+
- [ ] Lazy initialization used only when necessary, with correct idiom
|
|
175
|
+
- [ ] No dependence on thread scheduler behavior (`Thread.yield`, priorities)
|
|
176
|
+
|
|
177
|
+
**Red flags**: Non-volatile field used as stop flag across threads. Long computation
|
|
178
|
+
inside synchronized block. `wait()` without loop. `new Thread(runnable).start()` instead
|
|
179
|
+
of executor. Missing thread safety documentation. Single-check idiom used where
|
|
180
|
+
double-check is required.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 11. Serialization
|
|
185
|
+
|
|
186
|
+
- [ ] Java serialization avoided (JSON, protobuf, or other formats preferred)
|
|
187
|
+
- [ ] If Serializable: considered impact on flexibility and security
|
|
188
|
+
- [ ] If Serializable: custom serialized form used where default is inappropriate
|
|
189
|
+
- [ ] If Serializable: `readObject` validates defensively like a constructor
|
|
190
|
+
- [ ] If Serializable: enum types preferred for instance-controlled classes
|
|
191
|
+
- [ ] If Serializable: serialization proxy pattern considered
|
|
192
|
+
- [ ] No deserialization of untrusted data
|
|
193
|
+
|
|
194
|
+
**Red flags**: `ObjectInputStream.readObject()` on untrusted input. Default serialized
|
|
195
|
+
form exposing internal representation. `readObject` that doesn't validate or make
|
|
196
|
+
defensive copies. Non-enum singleton implementing `Serializable` without `readResolve`
|
|
197
|
+
or serialization proxy.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Severity Classification
|
|
202
|
+
|
|
203
|
+
When reporting issues, classify them:
|
|
204
|
+
|
|
205
|
+
- **Critical**: Bug, security vulnerability, or data corruption risk
|
|
206
|
+
(e.g., missing synchronization on shared mutable data, deserializing untrusted data,
|
|
207
|
+
broken equals/hashCode contract, empty catch block hiding failures)
|
|
208
|
+
- **Major**: Significant design debt or maintenance burden
|
|
209
|
+
(e.g., concrete class inheritance, raw types, mutable class that should be immutable,
|
|
210
|
+
telescoping constructors, checked exceptions that should be unchecked)
|
|
211
|
+
- **Minor**: Best practice deviation with limited immediate impact
|
|
212
|
+
(e.g., missing @Override, toString not implemented, unnecessary object creation,
|
|
213
|
+
for-loop instead of for-each)
|
|
214
|
+
- **Suggestion**: Improvement that would be nice but isn't urgent
|
|
215
|
+
(e.g., consider Builder for future extensibility, evaluate switching to Optional
|
|
216
|
+
return type, document thread safety level)
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
checkstyle_setup.py - Set up Checkstyle with an Effective Java-aligned configuration.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
python checkstyle_setup.py [--output-dir ./]
|
|
7
|
+
|
|
8
|
+
Generates:
|
|
9
|
+
effective-java-checkstyle.xml - Checkstyle rules mapped to Effective Java items
|
|
10
|
+
run_checkstyle.sh - Shell script to run Checkstyle on src/
|
|
11
|
+
|
|
12
|
+
Each config section references the Effective Java item it enforces.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import argparse
|
|
16
|
+
import os
|
|
17
|
+
import pathlib
|
|
18
|
+
import stat
|
|
19
|
+
import sys
|
|
20
|
+
import urllib.request
|
|
21
|
+
import urllib.error
|
|
22
|
+
|
|
23
|
+
CHECKSTYLE_VERSION = "10.14.2"
|
|
24
|
+
CHECKSTYLE_JAR = f"checkstyle-{CHECKSTYLE_VERSION}-all.jar"
|
|
25
|
+
CHECKSTYLE_URL = (
|
|
26
|
+
f"https://github.com/checkstyle/checkstyle/releases/download/"
|
|
27
|
+
f"checkstyle-{CHECKSTYLE_VERSION}/{CHECKSTYLE_JAR}"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
CHECKSTYLE_XML = """\
|
|
31
|
+
<?xml version="1.0"?>
|
|
32
|
+
<!DOCTYPE module PUBLIC
|
|
33
|
+
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
|
34
|
+
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
|
35
|
+
|
|
36
|
+
<!--
|
|
37
|
+
Effective Java - Checkstyle Configuration
|
|
38
|
+
Each module references the Effective Java item it enforces.
|
|
39
|
+
Book: "Effective Java" by Joshua Bloch, 3rd Edition.
|
|
40
|
+
-->
|
|
41
|
+
<module name="Checker">
|
|
42
|
+
<property name="severity" value="warning"/>
|
|
43
|
+
|
|
44
|
+
<module name="TreeWalker">
|
|
45
|
+
|
|
46
|
+
<!--
|
|
47
|
+
Item 15: Minimize the accessibility of classes and members.
|
|
48
|
+
Prefer private fields; expose only what is necessary.
|
|
49
|
+
-->
|
|
50
|
+
<module name="VisibilityModifier">
|
|
51
|
+
<property name="protectedAllowed" value="false"/>
|
|
52
|
+
<property name="publicMemberPattern" value="^serialVersionUID$"/>
|
|
53
|
+
</module>
|
|
54
|
+
|
|
55
|
+
<!--
|
|
56
|
+
Item 17: Minimize mutability — utility/helper classes should be final.
|
|
57
|
+
FinalClass flags classes with only private constructors that are not final.
|
|
58
|
+
-->
|
|
59
|
+
<module name="FinalClass"/>
|
|
60
|
+
|
|
61
|
+
<!--
|
|
62
|
+
Item 10: Obey the general contract when overriding equals.
|
|
63
|
+
Always override hashCode when you override equals.
|
|
64
|
+
-->
|
|
65
|
+
<module name="EqualsHashCode"/>
|
|
66
|
+
|
|
67
|
+
<!--
|
|
68
|
+
Item 34: Use enums instead of int constants.
|
|
69
|
+
Magic numbers in code signal that an enum or named constant should be used.
|
|
70
|
+
-->
|
|
71
|
+
<module name="MagicNumber">
|
|
72
|
+
<property name="ignoreNumbers" value="-1, 0, 1, 2"/>
|
|
73
|
+
<property name="ignoreAnnotation" value="true"/>
|
|
74
|
+
<property name="ignoreHashCodeMethod" value="true"/>
|
|
75
|
+
</module>
|
|
76
|
+
|
|
77
|
+
<!--
|
|
78
|
+
Item 77: Don't ignore exceptions.
|
|
79
|
+
Empty catch blocks hide failures; always handle or rethrow.
|
|
80
|
+
-->
|
|
81
|
+
<module name="EmptyCatchBlock">
|
|
82
|
+
<property name="exceptionVariableName" value="expected|ignore"/>
|
|
83
|
+
</module>
|
|
84
|
+
|
|
85
|
+
<!--
|
|
86
|
+
Item 2: Consider a builder when faced with many constructor parameters.
|
|
87
|
+
More than 3 parameters is a signal to introduce a Builder.
|
|
88
|
+
-->
|
|
89
|
+
<module name="ParameterNumber">
|
|
90
|
+
<property name="max" value="3"/>
|
|
91
|
+
<property name="tokens" value="METHOD_DEF, CTOR_DEF"/>
|
|
92
|
+
</module>
|
|
93
|
+
|
|
94
|
+
<!--
|
|
95
|
+
General best practice aligned with Effective Java's emphasis on small,
|
|
96
|
+
focused methods. Methods longer than 30 lines are harder to reason about.
|
|
97
|
+
-->
|
|
98
|
+
<module name="MethodLength">
|
|
99
|
+
<property name="max" value="30"/>
|
|
100
|
+
<property name="countEmpty" value="false"/>
|
|
101
|
+
</module>
|
|
102
|
+
|
|
103
|
+
<!--
|
|
104
|
+
Item 11: Always override toString.
|
|
105
|
+
Not directly checkable, but HideUtilityClassConstructor complements
|
|
106
|
+
Item 4 (enforce non-instantiability with private constructor).
|
|
107
|
+
-->
|
|
108
|
+
<module name="HideUtilityClassConstructor"/>
|
|
109
|
+
|
|
110
|
+
<!--
|
|
111
|
+
Item 57: Minimize the scope of local variables.
|
|
112
|
+
Inner assignments make scope harder to reason about.
|
|
113
|
+
-->
|
|
114
|
+
<module name="InnerAssignment"/>
|
|
115
|
+
|
|
116
|
+
<!--
|
|
117
|
+
Item 67: Optimize judiciously — avoid redundant string concatenation in loops.
|
|
118
|
+
-->
|
|
119
|
+
<module name="StringLiteralEquality"/>
|
|
120
|
+
|
|
121
|
+
</module>
|
|
122
|
+
</module>
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
RUN_SCRIPT = """\
|
|
126
|
+
#!/usr/bin/env bash
|
|
127
|
+
# run_checkstyle.sh
|
|
128
|
+
# Runs Checkstyle with the Effective Java configuration against src/
|
|
129
|
+
# Generated by checkstyle_setup.py
|
|
130
|
+
|
|
131
|
+
set -euo pipefail
|
|
132
|
+
|
|
133
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
134
|
+
JAR="${SCRIPT_DIR}/{jar}"
|
|
135
|
+
CONFIG="${SCRIPT_DIR}/effective-java-checkstyle.xml"
|
|
136
|
+
SRC_DIR="${1:-src}"
|
|
137
|
+
|
|
138
|
+
if [[ ! -f "$JAR" ]]; then
|
|
139
|
+
echo "ERROR: Checkstyle jar not found at $JAR"
|
|
140
|
+
echo "Run: python checkstyle_setup.py --output-dir \\"$(dirname "$JAR")\\""
|
|
141
|
+
exit 1
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
if [[ ! -d "$SRC_DIR" ]]; then
|
|
145
|
+
echo "ERROR: Source directory not found: $SRC_DIR"
|
|
146
|
+
echo "Usage: ./run_checkstyle.sh [src-dir]"
|
|
147
|
+
exit 1
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
echo "Running Checkstyle on $SRC_DIR ..."
|
|
151
|
+
java -jar "$JAR" -c "$CONFIG" -r "$SRC_DIR"
|
|
152
|
+
echo "Done."
|
|
153
|
+
""".format(jar=CHECKSTYLE_JAR)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def download_jar(output_dir: pathlib.Path) -> bool:
|
|
157
|
+
jar_path = output_dir / CHECKSTYLE_JAR
|
|
158
|
+
if jar_path.exists():
|
|
159
|
+
print(f"Checkstyle jar already present: {jar_path}")
|
|
160
|
+
return True
|
|
161
|
+
print(f"Downloading Checkstyle {CHECKSTYLE_VERSION} from GitHub ...")
|
|
162
|
+
try:
|
|
163
|
+
urllib.request.urlretrieve(CHECKSTYLE_URL, jar_path)
|
|
164
|
+
print(f"Downloaded: {jar_path}")
|
|
165
|
+
return True
|
|
166
|
+
except urllib.error.URLError as exc:
|
|
167
|
+
print(f"Download failed: {exc}")
|
|
168
|
+
print()
|
|
169
|
+
print("To install manually:")
|
|
170
|
+
print(f" curl -L -o {jar_path} \\")
|
|
171
|
+
print(f" {CHECKSTYLE_URL}")
|
|
172
|
+
return False
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def write_file(path: pathlib.Path, content: str, executable: bool = False) -> None:
|
|
176
|
+
path.write_text(content, encoding="utf-8")
|
|
177
|
+
if executable:
|
|
178
|
+
path.chmod(path.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
|
179
|
+
print(f"Wrote: {path}")
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def main() -> None:
|
|
183
|
+
parser = argparse.ArgumentParser(
|
|
184
|
+
description="Set up Checkstyle with an Effective Java-aligned configuration."
|
|
185
|
+
)
|
|
186
|
+
parser.add_argument(
|
|
187
|
+
"--output-dir",
|
|
188
|
+
default=".",
|
|
189
|
+
help="Directory to write config files and download the jar (default: ./)",
|
|
190
|
+
)
|
|
191
|
+
args = parser.parse_args()
|
|
192
|
+
|
|
193
|
+
output_dir = pathlib.Path(args.output_dir).resolve()
|
|
194
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
195
|
+
|
|
196
|
+
download_jar(output_dir)
|
|
197
|
+
|
|
198
|
+
write_file(output_dir / "effective-java-checkstyle.xml", CHECKSTYLE_XML)
|
|
199
|
+
write_file(output_dir / "run_checkstyle.sh", RUN_SCRIPT, executable=True)
|
|
200
|
+
|
|
201
|
+
print()
|
|
202
|
+
print("Setup complete.")
|
|
203
|
+
print(f" Config : {output_dir / 'effective-java-checkstyle.xml'}")
|
|
204
|
+
print(f" Runner : {output_dir / 'run_checkstyle.sh'}")
|
|
205
|
+
print()
|
|
206
|
+
print("Run Checkstyle:")
|
|
207
|
+
print(f" cd {output_dir} && ./run_checkstyle.sh [src-dir]")
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
if __name__ == "__main__":
|
|
211
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|