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
11 changes: 11 additions & 0 deletions internal/config/allowlist/allowed_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ func TestIsAllowedExt(t *testing.T) {
{".KT", true},
{".kts", true},
{".KTS", true},
{".fs", true},
{".FS", true},
{".fsi", true},
{".FSI", true},
{".fsx", true},
{".FSX", true},
{".ftl", true},
{".FTL", true},
{".ftlh", true},
Expand Down Expand Up @@ -163,6 +169,11 @@ func TestIsExcludedPath(t *testing.T) {
{"kotlin scripts test dir", "src/test/kotlin/scripts/FooTest.kts", true},
{"kotlin scripts main dir", "src/main/kotlin/scripts/Foo.kts", false},

// F# test files
{"fsharp Test suffix", "src/Domain/OrderTest.fs", true},
{"fsharp Test suffix at root", "OrderTest.fs", true},
{"fsharp non-test", "src/Domain/TestSupport.fs", false},

// JS/TS test files
{"js test file", "src/utils.test.js", true},
{"tsx test file", "src/Component.test.tsx", true},
Expand Down
1 change: 1 addition & 0 deletions internal/config/allowlist/default_exclude_patterns.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"**/*_test.go",
"**/src/test/java/**/*.java",
"**/src/test/**/*.{kt,kts}",
"**/*Test.fs",
"**/*.test.{js,jsx,ts,tsx}",
"**/*.spec.{js,jsx,ts,tsx}",
"**/__tests__/**",
Expand Down
2 changes: 2 additions & 0 deletions internal/config/allowlist/supported_file_types.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
".cs",
".vb",
".fs",
".fsi",
".fsx",
".go",
".rs",
".rb",
Expand Down
37 changes: 37 additions & 0 deletions internal/config/rules/rule_docs/fsharp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
> Favor precision over recall: report only defects that are likely to cause incorrect behavior, security vulnerabilities, resource leaks, or material performance problems. Do not report formatting that Fantomas can fix, or replace a project's established F# style with a personal preference. This rule covers F# implementation (`.fs`), signature (`.fsi`), and script (`.fsx`) files; account for the target framework and the surrounding .NET APIs before raising compatibility findings.

#### Discriminated Unions and Pattern Matching
- `match` expressions that omit a reachable discriminated-union or `option` case, especially after a union gains a new case; do not report a match that the compiler can prove exhaustive
- Catch-all `_` branches used only to suppress an incomplete-pattern warning when an omitted case needs distinct behavior or error handling
- Active patterns or guards whose ordering shadows a later reachable case, silently selecting the wrong branch
- `Option.get`, `ValueOption.get`, accessing `.Value` on an option/value option, or project-specific partial `Result` unwraps where `None`, `ValueNone`, or `Error` can occur for runtime, external, or untrusted input
- Treating a domain failure as an exception while callers are otherwise required to handle it through `Result`; do not flag an intentionally documented exception boundary

#### Resource Lifetime and Mutable State
- `IDisposable`, streams, database connections, locks, or cancellation registrations acquired without `use`, `use!`, `try/finally`, or an equivalent cleanup path that covers exceptions and early returns
- A resource returned from a `use` scope, captured by a closure that outlives the scope, or disposed before an asynchronous workflow that still consumes it completes
- Mutable state shared between agents, tasks, event callbacks, or parallel collection operations without synchronization or a clear single-owner protocol
- Reusing a mutable buffer, array, or record across asynchronous operations where a later mutation can race with a consumer; ordinary local mutation with no escaping reference is not a finding

#### Async, Tasks, and Cancellation
- `Task` or `Async` workflows that drop a reachable exception, cancellation, or result instead of propagating or intentionally handling it at the boundary
- Calling `.Result`, `.Wait()`, or `Async.RunSynchronously` on a context that can require asynchronous progress, producing a deadlock or thread-pool starvation risk
- Accepting a `CancellationToken` but failing to pass it into a cancellable I/O, delay, HTTP, database, or child task operation when the API supports it
- Starting background work without retaining, awaiting, supervising, or observing the task's exception; do not flag a deliberately detached process when its lifetime and error reporting are explicit

#### Sequences, Collections, and Performance
- Enumerating a `seq` with side effects or an expensive source multiple times when the result is expected to be stable or when repeated execution changes behavior; materialize once only when the code needs repeated traversal
- Calling `Seq.head`, `Seq.reduce`, indexed access, or a map lookup without establishing that the collection/key is present for non-constant input
- Accidentally forcing a lazy sequence in a hot path, or composing a sequence pipeline whose deferred exceptions escape a boundary that promises eager validation
- Quadratic list append, repeated immutable-map updates, or repeated string concatenation in a loop where input size can make the behavior materially expensive; do not replace concise collection code merely for micro-optimizations

#### .NET Interop and Type Boundaries
- Passing F# `option` values through a .NET API as though they were `null`, or treating a nullable/reference return from .NET as non-null without a local invariant
- P/Invoke, reflection, serialization, or JSON bindings whose declared types, field names, nullability, ownership, or enum values do not match the external contract
- Runtime downcasts or unchecked/default-producing operations (`:?>`, `unbox`, `Unchecked.defaultof`, or reflection-based invocation) without a locally established runtime type/nullability invariant
- Untrusted values flowing into SQL, shell commands, file paths, URLs, deserialization, or HTML without validation or parameterization, and secrets written to source, logs, or error messages

#### Signatures and Module Boundaries
- An `.fsi` signature whose exposed types, arity, generic constraints, mutability, or visibility do not match the implementation or intended public API
- Public functions that leak mutable implementation state or an internal representation where callers can violate the module's invariants
- Module initialization with observable I/O, non-deterministic global state, or exceptions that make importing the module fail unexpectedly; do not report explicit, documented application bootstrap code
1 change: 1 addition & 0 deletions internal/config/rules/system_rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"**/*.astro": "astro.md",
"**/*.{ts,js,tsx,jsx,mjs,cjs}": "ts_js_tsx_jsx.md",
"**/*.{kt,kts}": "kotlin.md",
"**/*.{fs,fsi,fsx}": "fsharp.md",
"**/*.rs": "rust.md",
"**/*.{cpp,cc,cxx,hpp,hxx}": "cpp.md",
"**/*.c": "c.md",
Expand Down
3 changes: 3 additions & 0 deletions internal/config/rules/system_rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ func TestResolve_DefaultRules(t *testing.T) {
{"server/bootstrap.cjs", "TypeScript"},
{"app.kt", "Null Safety"},
{"scripts/setup.kts", "Null Safety"},
{"src/domain/Order.fs", "Discriminated Unions and Pattern Matching"},
{"src/domain/Order.fsi", "Discriminated Unions and Pattern Matching"},
{"scripts/migrate.fsx", "Discriminated Unions and Pattern Matching"},
{"src/main/handler.cpp", "Smart Pointer"},
{"src/main/handler.cxx", "Smart Pointer"},
{"include/handler.hxx", "Smart Pointer"},
Expand Down
2 changes: 2 additions & 0 deletions pages/src/content/docs/en/review-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ generated code, and vendored dependencies:
- `**/*_test.go`
- `**/src/test/java/**/*.java`
- `**/src/test/**/*.{kt,kts}`
- `**/*Test.fs`
- `**/*.test.{js,jsx,ts,tsx}`
- `**/*.spec.{js,jsx,ts,tsx}`
- `**/__tests__/**`
Expand Down Expand Up @@ -230,6 +231,7 @@ matching order:
| `**/*.astro` | `astro.md` — Astro components and islands. |
| `**/*.{ts,js,tsx,jsx,mjs,cjs}` | `ts_js_tsx_jsx.md` |
| `**/*.{kt,kts}` | `kotlin.md` |
| `**/*.{fs,fsi,fsx}` | `fsharp.md` — F# implementation, signature, and script files. |
| `**/*.rs` | `rust.md` |
| `**/*.R` | `r.md` |
| `**/*.{cpp,cc,cxx,hpp,hxx}` | `cpp.md` |
Expand Down
2 changes: 2 additions & 0 deletions pages/src/content/docs/ja/review-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ OCR は [`bmatcuk/doublestar/v4`](https://pkg.go.dev/github.com/bmatcuk/doublest
- `**/*_test.go`
- `**/src/test/java/**/*.java`
- `**/src/test/**/*.{kt,kts}`
- `**/*Test.fs`
- `**/*.test.{js,jsx,ts,tsx}`
- `**/*.spec.{js,jsx,ts,tsx}`
- `**/__tests__/**`
Expand Down Expand Up @@ -188,6 +189,7 @@ OCR は [`bmatcuk/doublestar/v4`](https://pkg.go.dev/github.com/bmatcuk/doublest
| `**/*.astro` | `astro.md`: Astro コンポーネントと islands。 |
| `**/*.{ts,js,tsx,jsx,mjs,cjs}` | `ts_js_tsx_jsx.md` |
| `**/*.{kt,kts}` | `kotlin.md` |
| `**/*.{fs,fsi,fsx}` | `fsharp.md`: F# の実装、シグネチャ、スクリプトファイル。 |
| `**/*.rs` | `rust.md` |
| `**/*.R` | `r.md` |
| `**/*.{cpp,cc,cxx,hpp,hxx}` | `cpp.md` |
Expand Down
2 changes: 2 additions & 0 deletions pages/src/content/docs/ko/review-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ OCR은 [`bmatcuk/doublestar/v4`](https://pkg.go.dev/github.com/bmatcuk/doublesta
- `**/*_test.go`
- `**/src/test/java/**/*.java`
- `**/src/test/**/*.{kt,kts}`
- `**/*Test.fs`
- `**/*.test.{js,jsx,ts,tsx}`
- `**/*.spec.{js,jsx,ts,tsx}`
- `**/__tests__/**`
Expand Down Expand Up @@ -218,6 +219,7 @@ diff 단계에서 일어납니다.
| `**/*.astro` | `astro.md` — Astro 컴포넌트와 아일랜드. |
| `**/*.{ts,js,tsx,jsx,mjs,cjs}` | `ts_js_tsx_jsx.md` |
| `**/*.{kt,kts}` | `kotlin.md` |
| `**/*.{fs,fsi,fsx}` | `fsharp.md` — F# 구현, 시그니처, 스크립트 파일. |
| `**/*.rs` | `rust.md` |
| `**/*.R` | `r.md` |
| `**/*.{cpp,cc,cxx,hpp,hxx}` | `cpp.md` |
Expand Down
2 changes: 2 additions & 0 deletions pages/src/content/docs/ru/review-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ OCR использует [`bmatcuk/doublestar/v4`](https://pkg.go.dev/github.com
- `**/*_test.go`
- `**/src/test/java/**/*.java`
- `**/src/test/**/*.{kt,kts}`
- `**/*Test.fs`
- `**/*.test.{js,jsx,ts,tsx}`
- `**/*.spec.{js,jsx,ts,tsx}`
- `**/__tests__/**`
Expand Down Expand Up @@ -230,6 +231,7 @@ OCR использует [`bmatcuk/doublestar/v4`](https://pkg.go.dev/github.com
| `**/*.astro` | `astro.md` — компоненты и islands Astro. |
| `**/*.{ts,js,tsx,jsx,mjs,cjs}` | `ts_js_tsx_jsx.md` |
| `**/*.{kt,kts}` | `kotlin.md` |
| `**/*.{fs,fsi,fsx}` | `fsharp.md` — файлы реализации, сигнатур и скриптов F#. |
| `**/*.rs` | `rust.md` |
| `**/*.R` | `r.md` |
| `**/*.{cpp,cc,cxx,hpp,hxx}` | `cpp.md` |
Expand Down
2 changes: 2 additions & 0 deletions pages/src/content/docs/zh/review-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ OCR 用 [`bmatcuk/doublestar/v4`](https://pkg.go.dev/github.com/bmatcuk/doublest
- `**/*_test.go`
- `**/src/test/java/**/*.java`
- `**/src/test/**/*.{kt,kts}`
- `**/*Test.fs`
- `**/*.test.{js,jsx,ts,tsx}`
- `**/*.spec.{js,jsx,ts,tsx}`
- `**/__tests__/**`
Expand Down Expand Up @@ -209,6 +210,7 @@ OCR 用 [`bmatcuk/doublestar/v4`](https://pkg.go.dev/github.com/bmatcuk/doublest
| `**/*.astro` | `astro.md`——Astro 组件与 islands。 |
| `**/*.{ts,js,tsx,jsx,mjs,cjs}` | `ts_js_tsx_jsx.md` |
| `**/*.{kt,kts}` | `kotlin.md` |
| `**/*.{fs,fsi,fsx}` | `fsharp.md`——F# 实现、签名和脚本文件。 |
| `**/*.rs` | `rust.md` |
| `**/*.R` | `r.md` |
| `**/*.{cpp,cc,cxx,hpp,hxx}` | `cpp.md` |
Expand Down
Loading