Fork of OneScript 2.2.0 · MPL-2.0 · v2.2.0-vanteam.2

Preprocessor fix and -checkall

Check 1C modules to the end in one run: every error of a module, and unknown 1C globals no longer stop the check.

$ oscript -checkall src/cf Заказ.bsl: Ошибка в строке: 7,3 / Ожидается символ: Тогда Заказ.bsl: unknown symbols: 3 (Справочники; …) Files: 76, with errors: 1, not checked: 0
2.4 s76 modules in one run; 50–80 s with a process per file
116 / 116real modules checked to the end; -check: 10
90 → 0false preprocessor errors in 11,275 real 1C modules

Checking 76 modules

project modules of a 1C:Enterprise 8.3 configuration, wall time
0 s30 s60 s90 s1.9.4 -check1.9.4 -check: 50.0 s50.0 s2.2.0 -check2.2.0 -check: 80.4 s80.4 svanteam.2 -checkvanteam.2 -check: 67.1 s67.1 svanteam.2 -checkallvanteam.2 -checkall: 2.4 s2.4 s
-check, one process per file-checkall, one run
-checkall · v2.2.0-vanteam.2

Every error of every module, in one run

On 1C modules oscript -check nearly always meets a name OneScript does not have — Справочники, Документы, a common module — and stops. OneScript 2.x parses the whole module first, so syntax is still checked in full, but the code generator checks after that point never run: argument count of the module's own methods, a procedure used as a function, a duplicate method, labels. OneScript 1.9.4 compiles in one pass and sees nothing at all after the first unknown name. Each -check also starts the engine: about 0.7 s of 0.9 s per file.

-checkall starts the engine once for all files, collects errors instead of stopping at the first, and lists unknown names separately. -check itself is unchanged. The 2.2.0-vanteam.2 build is also published with ReadyToRun.

Checking 76 modules

0 s15 s30 s45 s60 s75 s90 s1.9.4 -check1.9.4 -check: 50.0 s50.0 s2.2.0 -check2.2.0 -check: 80.4 s80.4 svanteam.2 -checkvanteam.2 -check: 67.1 s67.1 svanteam.2 -checkallvanteam.2 -checkall: 2.4 s2.4 s
-check, one process per file-checkall, one run

Project modules of a 1C:Enterprise 8.3 configuration, wall time of one short run on a loaded machine.

Data
ModeSeconds
1.9.4 -check49.96
2.2.0 -check80.41
2.2.0-vanteam.2 -check67.12
2.2.0-vanteam.2 -checkall2.38

One 155 KB module

0 s0.2 s0.4 s0.6 s0.8 s1.9.4 -check1.9.4 -check: 0.51 s0.51 s2.2.0 -check2.2.0 -check: 0.69 s0.69 s2.2.0-vanteam.1 -check2.2.0-vanteam.1 -check: 0.69 s0.69 svanteam.2 -checkvanteam.2 -check: 0.48 s0.48 svanteam.2 -checkallvanteam.2 -checkall: 0.61 s0.61 s
-check-checkall

Median of 7 interleaved runs. ReadyToRun makes plain -check about a third faster than the official 2.2.0.

Data
ModeMedian, s
1.9.4 -check0.513
2.2.0 -check0.688
2.2.0-vanteam.1 -check0.693
2.2.0-vanteam.2 -check0.477
2.2.0-vanteam.2 -checkall0.614

What each engine finds

19 hand-written modules with known error lines, each starting with a Справочники call like real 1C code; 116 real modules (76 of an УПП project, 40 common modules of УТ 10.3). 1.9.4 and 2.2.0 use -check, the fork uses -checkall.

Found1.9.42.2.02.2.0-vanteam.2
Syntax errors after an unknown 1C global0 / 1010 / 1010 / 10
Code generator errors after an unknown global0 / 40 / 44 / 4
Both errors of a module with two0 / 42 / 44 / 4
Valid modules without a false error3 / 32 / 33 / 3
Real modules checked to the end10 / 11610 / 116116 / 116
Preprocessor tests (tests/preprocessor-skipped-branch.os)13 / 144 / 1414 / 14

Usage

oscript -encoding=utf-8 -checkall <file or folder> [...]
  <file>: Ошибка в строке: N,M / message      every error of the module
  <file>: No errors.
  <file>: unknown symbols: K (...)           the 1C global context, not an error
  Files: X, with errors: Y, not checked: Z
Exit code: 0 no errors, 1 errors, 2 a file could not be checked.

OneScript defines no 1C preprocessor symbols, so code under #Если Сервер Тогда is an inactive branch and is skipped by any mode. To check it, also pass a copy of the module with the directive lines blanked out; line numbers stay the same.

The bug

A flag that never resets

When an #Если condition is false, the preprocessor skips the branch and looks for the next #. It trusted the iterator's OnNewLine, which only changes when a lexeme is read — so it stayed true for the whole skipped branch, and any # became a directive.

One line, character by character

CharacterА␣=␣"цвет␣#000000";
OnNewLine in 2.2.0●●●●●●●●●●●●●●●●●●●
Line start in the fork●··················

● true, · false. The # is the 11th character; 2.2.0 accepts it as a directive and fails at column 12, where the lexer expects a letter.

OneScript 2.2.0

while (true)
{
    if (iterator.CurrentSymbol == SpecialChars.Preprocessor)
    {
        if(iterator.OnNewLine)
            return true;
    }
    if (!iterator.MoveNext())
        break;
    iterator.SkipSpaces();
}

This fork

var lineStart = iterator.CurrentSymbol == '\n';var contentLine = iterator.CurrentLine;while (iterator.SkipSpaces()){
    if (iterator.CurrentLine != contentLine)        lineStart = true;    if (lineStart && iterator.CurrentSymbol == SpecialChars.Preprocessor)        return true;    lineStart = false;    contentLine = iterator.CurrentLine;    if (!iterator.MoveNext())
        break;
}
Tests

Failing tests first

28 new tests in PreprocessorTests: 14 scenarios, each with CRLF and LF line endings. The other engine test projects pass, and the upstream script suite (tests/testrunner.os, 1,092 tests) gives the same result for every test as a control build of the same commit without the fix.

OneScript.Language.Tests

Upstream 2.2.0Upstream 2.2.0 — 175 passed175 passedUpstream 2.2.0 — 23 failed23 failedThis forkThis fork — 198 passed198 passed
passedfailed

Five of the new tests also pass on upstream: four guard tests that require real errors to stay errors, and the CRLF variant of the #КонецОбласти case — that defect shows only with LF.

Upstream script suite

Control buildControl build — 1,086 passed1,086 passedControl build — 2 failedControl build — 4 skipped2 failed · 4 skippedThis forkThis fork — 1,086 passed1,086 passedThis fork — 2 failedThis fork — 4 skipped2 failed · 4 skipped
passedfailed: environment (console, eval)skipped

0 differences across 1,092 tests. The two failures are the same in both builds and come from the test environment.

Control cases

19 files, four engines

oscript -check on hand-written cases. Windows is defined by OneScript on Windows (an active branch), Клиент is not (an inactive one). A red ring marks a result that differs from the expected one. The control build equals the official 2.2.0 on all 19.

CaseExpected1.9.42.2.02.2.0 controlfork
inactive_hash✓ no errors✓✕✕✓
inactive_hash_lf✓ no errors✓✕✕✓
directive_names_in_strings✓ no errors✓✕✕✓
multiline_string✓ no errors✓✕✕✓
comments✓ no errors✓✕✕✓
indented_directives✓ no errors✓✕✕✓
nested_else_elseif✓ no errors✓✕✕✓
solved_branch✓ no errors✓✕✕✓
region_endif_crlf✓ no errors✓✓✓✓
region_endif_lf✓ no errors✓✕✕✓
unclosed_comment✕ error✕✓✓✕
unclosed_string✕ error✕✕✕✕
midline_endif✕ error✕✓✓✕
invalid_directive_line_start✕ error✓✕✕✕
active_midline_directive✕ error✕✕✕✕
active_syntax_error✕ error✕✕✕✕
strfind✓ no errors✓✓✓✓
evidence_inactive_hash✓ no errors✓✕✕✓
evidence_strfind✓ no errors✓✓✓✓
Real code

11,275 modules of a 1C:Enterprise 8.3 configuration

A configuration dump, the project's own modules and its archived builds, each checked by both engines. Every difference has the same shape: 2.2.0 stops at a # inside a string literal — HTML colours, code templates, query-text placeholders.

False preprocessor errors

0204060Configuration dump — 2.2.0: 29290Configuration dumpProject modules — 2.2.0: 110Project modulesArchived builds — 2.2.0: 60600Archived builds
OneScript 2.2.0this fork
Data
Module setFiles2.2.0Fork
Configuration dump3,667290
Project modules7610
Archived builds7,532600

Median check time per file

0.7 s0.75 s0.8 s0.85 s0.9 s0.95 s1 sConfiguration dumpConfiguration dump — before: 0.92 sConfiguration dump — after: 0.92 s0.920.92Project modulesProject modules — before: 0.94 sProject modules — after: 0.92 s0.920.94Archived buildsArchived builds — before: 0.88 sArchived builds — after: 0.86 s0.860.88
OneScript 2.2.0this fork

Unchanged: process start-up dominates.

Data
Module set2.2.0, sFork, s
Configuration dump0.9200.920
Project modules0.9450.920
Archived builds0.8800.860

What the fork reports instead

90 differing modules90 differing modules — 75 pass75 pass90 differing modules — 15 later 1C-context error15 later 1C-context error

On all 90 modules the result and the error line match OneScript 1.9.4. The later errors are Неизвестный символ: the 1C global context does not exist in OneScript. Since -check stops at the first error, 90 is a lower bound. No module got worse.

Use it

Build from source

git clone https://github.com/ivanbokhan84/OneScript.git
cd OneScript
dotnet test src/Tests/OneScript.Language.Tests/OneScript.Language.Tests.csproj -c Release -p:Platform=AnyCPU
dotnet publish src/oscript/oscript.csproj -r win-x64 --self-contained -c Release -p:VersionPrefix=2.2.0 -p:VersionSuffix=vanteam.2 -p:PublishReadyToRun=true -o dist/bin