Skip to content

к #1532: ОткрытьПоток для ЗаписьJSON#1714

Open
Mr-Rm wants to merge 5 commits into
EvilBeaver:developfrom
Mr-Rm:v2/fix-1532-jsonwriter
Open

к #1532: ОткрытьПоток для ЗаписьJSON#1714
Mr-Rm wants to merge 5 commits into
EvilBeaver:developfrom
Mr-Rm:v2/fix-1532-jsonwriter

Conversation

@Mr-Rm

@Mr-Rm Mr-Rm commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Есть отличие от платформы 1С: при открытии read-only потока исключение по невозможности записи выбрасывается сразу. 1С отрабатывает открытие без ошибки, а исключение возникает только при попытке записи.
Обоснование:

  • при открытии read-only файла ошибка невозможности записи также проявляется сразу, в том числе в 1С;
  • вариант маловероятный, а дополнительная проверка возможности записывать потребуется при каждой операции записи

Summary by CodeRabbit

  • Bug Fixes
    • Added state validation to prevent JSON writing unless the writer is properly opened.
    • Added validation for null and read-only stream outputs.
    • Improved option handling so missing options reliably fall back to defaults.
  • Improvements
    • Added deterministic cleanup for the JSON writer (disposal).
    • Enhanced Close() behavior for in-memory/string outputs: it now flushes and returns generated JSON.
    • Reworked JSON escaping to produce consistent escaped sequences.
  • Tests
    • Added/updated tests for escaped symbols and memory-stream write behavior, including reuse after closing and error cases for read-only streams.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8406335e-8fc5-4f1e-b5a7-83af10a76a69

📥 Commits

Reviewing files that changed from the base of the PR and between 0c16452 and f4a1a41.

📒 Files selected for processing (2)
  • src/OneScript.StandardLibrary/Json/JSONWriter.cs
  • tests/json/test-json_writer.os
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/OneScript.StandardLibrary/Json/JSONWriter.cs

📝 Walkthrough

Walkthrough

JSONWriter now implements deterministic disposal, centralizes writer setup and open-state validation, handles null options, applies switch-based escaping, rejects read-only streams, and preserves external streams after closure.

Changes

JSONWriter lifecycle and output handling

Layer / File(s) Summary
Writer contract and option defaults
src/OneScript.StandardLibrary/Json/JSONWriter.cs
JSONWriter implements IDisposable, centralizes unopened-writer validation, applies default settings for null options, and updates property documentation.
Output setup and resource lifecycle
src/OneScript.StandardLibrary/Json/JSONWriter.cs, tests/json/test-json_writer.os
File, stream, and string outputs use shared writer initialization; Close() flushes and delegates cleanup to Dispose(), while tests verify stream output, returned JSON, and subsequent stream writes.
Write validation and escaping behavior
src/OneScript.StandardLibrary/Json/JSONWriter.cs, tests/json/test-json_writer.os
Write operations validate writer state, escaping uses switch-based mappings, and tests cover escaped symbols, renamed registration, and read-only stream failures.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant JSONTest
  participant JSONWriter
  participant MemoryStream
  JSONTest->>JSONWriter: open on writable stream
  JSONWriter->>MemoryStream: write JSON bytes
  JSONTest->>JSONWriter: Close()
  JSONWriter->>MemoryStream: flush and release writer
  JSONTest->>MemoryStream: append bytes after JSON close
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title is specific and matches the main change around opening a stream for ЗаписьJSON.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/OneScript.StandardLibrary/Json/JSONWriter.cs (1)

494-504: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Dispose closes the underlying writer after disposing its output — reverse the order.

_stringWriter?.Dispose() runs before _writer.Close(). _writer.Close() flushes and auto-completes into the underlying StringWriter, which has already been disposed. Close/flush _writer first, then dispose _stringWriter.

♻️ Proposed reorder
 protected virtual void Dispose(bool disposing)
 {
     if (disposing && _writer is not null)
     {
-        _stringWriter?.Dispose();
-        _stringWriter = null;
-
-        _writer.Close();
-        _writer = null;
+        _writer.Close();
+        _writer = null;
+
+        _stringWriter?.Dispose();
+        _stringWriter = null;
     }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/OneScript.StandardLibrary/Json/JSONWriter.cs` around lines 494 - 504,
Update JSONWriter.Dispose(bool disposing) to close _writer before disposing
_stringWriter, so the writer can flush and complete its output into the
underlying StringWriter; then clear and dispose the resources in the corrected
order while preserving the existing null checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/OneScript.StandardLibrary/Json/JSONWriter.cs`:
- Around line 468-484: Update SetString to close the currently open writer
before assigning a new StringWriter, then configure the new writer through
SetWriter. Preserve SetWriter’s existing cleanup behavior so reopening string
output retains the new _stringWriter and Close() returns its contents.
- Around line 267-274: The Close method reads _stringWriter before Dispose
closes the underlying writer, omitting auto-completed JSON delimiters. Update
Close to call Dispose before obtaining the string result, while preserving
String.Empty for non-string writers and returning the flushed content.

---

Nitpick comments:
In `@src/OneScript.StandardLibrary/Json/JSONWriter.cs`:
- Around line 494-504: Update JSONWriter.Dispose(bool disposing) to close
_writer before disposing _stringWriter, so the writer can flush and complete its
output into the underlying StringWriter; then clear and dispose the resources in
the corrected order while preserving the existing null checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 786882fc-ca23-49b8-a264-9b1439fb526c

📥 Commits

Reviewing files that changed from the base of the PR and between 863766c and 493f13c.

📒 Files selected for processing (1)
  • src/OneScript.StandardLibrary/Json/JSONWriter.cs

Comment on lines 267 to 274
public string Close()
{
string res = "";

if (IsOpenForString())
{
res = _stringWriter.ToString();
_stringWriter.Close();
_stringWriter = null;
}

if (_writer != null)
{
_writer.Close();
_writer = null;
}

return res;
var result = IsOpenForString() ? _stringWriter.ToString() : String.Empty;

Dispose();

return result;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Newtonsoft.Json JsonTextWriter AutoCompleteOnClose Flush behavior on Close

💡 Result:

In Newtonsoft.Json, the AutoCompleteOnClose property (which defaults to true) controls whether the JsonTextWriter automatically closes any open JSON objects or arrays when its Close method is called [1][2]. When Close is invoked, the behavior follows these steps: 1. Auto-completion: If AutoCompleteOnClose is true, the writer checks the current state of the JSON stack [2]. It will automatically write the necessary closing tokens (e.g., } for an object or ] for an array) for any nested structures that remain unclosed [2][3]. 2. Flushing and Closing: The JsonTextWriter then proceeds to close itself [4][5]. If the CloseOutput property is also set to true (which is its default behavior), the writer will additionally close the underlying TextWriter or stream that was passed to it [6][5]. It is important to note that while JsonTextWriter handles the completion of the JSON structure, it relies on the underlying stream or writer to handle physical data persistence [4]. If you want to ensure that all data is physically written to the destination without closing the underlying stream, you should explicitly call the Flush method before the writer is closed, and consider setting CloseOutput to false to prevent the JsonTextWriter from closing the underlying stream [6][7][8].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="src/OneScript.StandardLibrary/Json/JSONWriter.cs"

echo "== file outline =="
ast-grep outline "$FILE" --view expanded || true

echo
echo "== relevant slice =="
sed -n '1,340p' "$FILE" | cat -n | sed -n '1,340p'

Repository: EvilBeaver/OneScript

Length of output: 16803


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="src/OneScript.StandardLibrary/Json/JSONWriter.cs"

echo "== dispose/setwriter slice =="
sed -n '460,540p' "$FILE" | cat -n

echo
echo "== json writer close semantics from package sources if present =="
rg -n "AutoCompleteOnClose|CloseOutput|class JsonTextWriter|override void Close|Dispose\\(" -g '*.cs' -g '*.csproj' -g '*.props' -g '*.targets' .

Repository: EvilBeaver/OneScript

Length of output: 18866


Flush the JSON writer before reading the string. Close() captures _stringWriter.ToString() before _writer.Close() runs in Dispose(), so any auto-completed ]/} written on close won’t be included in the returned value. Move the read after Dispose() or close the writer first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/OneScript.StandardLibrary/Json/JSONWriter.cs` around lines 267 - 274, The
Close method reads _stringWriter before Dispose closes the underlying writer,
omitting auto-completed JSON delimiters. Update Close to call Dispose before
obtaining the string result, while preserving String.Empty for non-string
writers and returning the flushed content.

Comment thread src/OneScript.StandardLibrary/Json/JSONWriter.cs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/json/test-json_writer.os`:
- Around line 218-226: Update the test flow around ЗаписьJSON.УстановитьСтроку
and ЗаписьJSON.ЗаписатьБезОбработки to keep JSON output directed to the opened
stream by removing УстановитьСтроку. Adjust the assertions so
ЗаписьJSON.Закрыть() is expected to return an empty string, while the final
Поток buffer assertion expects the interleaved JSON bytes alongside the existing
binary data.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6c496d81-2a03-431c-9572-2465c9722dd2

📥 Commits

Reviewing files that changed from the base of the PR and between 5f656f7 and b10fbda.

📒 Files selected for processing (2)
  • src/OneScript.StandardLibrary/Json/JSONWriter.cs
  • tests/json/test-json_writer.os
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/OneScript.StandardLibrary/Json/JSONWriter.cs

Comment thread tests/json/test-json_writer.os Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant