From 81c8e7a5c66514e48ffb95e835e5329612977f96 Mon Sep 17 00:00:00 2001 From: Rostislav Rotaru Date: Sat, 14 Nov 2026 17:34:16 -0800 Subject: [PATCH 1/3] Prove the values five sites asserted non-null - The console reporter draws its progress frame from a text and a dot count rather than reading an array by index. - The two conformance tests check that their case's record exists with Assert.isDefined. - The for-in/of check destructures its first two declarations once, where it already returned for an empty list. - The rest-initializer check tests the binding element's equals node, which the parser sets exactly when it sets the initializer. Part of #96. Agent: DEV1 (developer) Agent-Model: Anthropic Opus 5.5, Medium --- src/noldova.context.testing/src/resources.ts | 4 +++- .../src/services/reporting/test-console-reporter.ts | 4 ++-- .../tests/conformance/conformance-cases.test.ts | 4 +++- .../typescript-binding-element.node.extensions.ts | 4 ++-- .../typescript-for-in-or-of-statement.node.extensions.ts | 5 ++--- .../tests/conformance/conformance-cases.test.ts | 3 ++- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/noldova.context.testing/src/resources.ts b/src/noldova.context.testing/src/resources.ts index 335195e9..40d38fb8 100644 --- a/src/noldova.context.testing/src/resources.ts +++ b/src/noldova.context.testing/src/resources.ts @@ -96,7 +96,9 @@ export class Resources { public static readonly terminalYellow: string = "\u001b[33m"; public static readonly terminalReset: string = "\u001b[0m"; public static readonly terminalClearLine: string = "\r\u001b[2K"; - public static readonly progressFrames: readonly string[] = ["Running tests.", "Running tests..", "Running tests..."]; + public static readonly progressText: string = "Running tests"; + public static readonly progressDot: string = "."; + public static readonly progressMaximumDots: number = 3; public static readonly progressIntervalMilliseconds: number = 300; public static readonly centisecondsPerSecond: number = 100; public static readonly durationDecimalPlaces: number = 2; diff --git a/src/noldova.context.testing/src/services/reporting/test-console-reporter.ts b/src/noldova.context.testing/src/services/reporting/test-console-reporter.ts index b91dc379..9dd11485 100644 --- a/src/noldova.context.testing/src/services/reporting/test-console-reporter.ts +++ b/src/noldova.context.testing/src/services/reporting/test-console-reporter.ts @@ -76,13 +76,13 @@ export class TestConsoleReporter implements ITestProgressListener { } private advanceProgress(): void { - this.progressFrame = (this.progressFrame + 1) % Resources.progressFrames.length; + this.progressFrame = (this.progressFrame + 1) % Resources.progressMaximumDots; this.drawProgress(); this.scheduleProgress(); } private drawProgress(): void { - this.write(`${Resources.terminalClearLine}${Resources.progressFrames[this.progressFrame]!}`); + this.write(`${Resources.terminalClearLine}${Resources.progressText}${Resources.progressDot.repeat(this.progressFrame + 1)}`); } private writeLines(lines: readonly string[]): void { diff --git a/src/parsers/noldova.context.parsers.regex/tests/conformance/conformance-cases.test.ts b/src/parsers/noldova.context.parsers.regex/tests/conformance/conformance-cases.test.ts index c883dd8a..7cdefd3d 100644 --- a/src/parsers/noldova.context.parsers.regex/tests/conformance/conformance-cases.test.ts +++ b/src/parsers/noldova.context.parsers.regex/tests/conformance/conformance-cases.test.ts @@ -24,7 +24,9 @@ export class ConformanceCasesTests { @TestMethod public matchesTest262UnlessKnownToFail(casePath: string): void { - const verdict = ConformanceCaseVerdict.of(ConformanceExpectationsReader.load().applicableRecords.get(casePath)!); + const record = ConformanceExpectationsReader.load().applicableRecords.get(casePath); + Assert.isDefined(record, casePath); + const verdict = ConformanceCaseVerdict.of(record); const failure = KnownFailuresLedger.load().failing.get(casePath); if (Object.isUndefined(failure)) diff --git a/src/parsers/noldova.context.parsers.typescript/src/extensions/nodes/declarations/typescript-binding-element.node.extensions.ts b/src/parsers/noldova.context.parsers.typescript/src/extensions/nodes/declarations/typescript-binding-element.node.extensions.ts index 742d59b3..cc7922de 100644 --- a/src/parsers/noldova.context.parsers.typescript/src/extensions/nodes/declarations/typescript-binding-element.node.extensions.ts +++ b/src/parsers/noldova.context.parsers.typescript/src/extensions/nodes/declarations/typescript-binding-element.node.extensions.ts @@ -36,8 +36,8 @@ TypeScriptBindingElementNode.prototype.hasTypeScriptBindingName = function (this }; TypeScriptBindingElementNode.prototype.reportTypeScriptRestInitializer = function (this: TypeScriptBindingElementNode, context: TypeScriptParserContext): void { - if (!Object.isUndefined(this.dotDotDotNode) && Object.isUndefined(this.propertyNameNode) && !Object.isUndefined(this.initializerNode)) - context.diagnosticCollector.addTypeScriptGrammarDiagnostic(context.source, TypeScriptDiagnosticTemplates.TS1186, this.equalsNode!.span); + if (!Object.isUndefined(this.dotDotDotNode) && Object.isUndefined(this.propertyNameNode) && !Object.isUndefined(this.equalsNode)) + context.diagnosticCollector.addTypeScriptGrammarDiagnostic(context.source, TypeScriptDiagnosticTemplates.TS1186, this.equalsNode.span); }; TypeScriptBindingElementNode.prototype.isTypeScriptRestElement = function (this: TypeScriptBindingElementNode): boolean { diff --git a/src/parsers/noldova.context.parsers.typescript/src/extensions/nodes/statements/typescript-for-in-or-of-statement.node.extensions.ts b/src/parsers/noldova.context.parsers.typescript/src/extensions/nodes/statements/typescript-for-in-or-of-statement.node.extensions.ts index 56fbb024..f7a3e714 100644 --- a/src/parsers/noldova.context.parsers.typescript/src/extensions/nodes/statements/typescript-for-in-or-of-statement.node.extensions.ts +++ b/src/parsers/noldova.context.parsers.typescript/src/extensions/nodes/statements/typescript-for-in-or-of-statement.node.extensions.ts @@ -42,7 +42,8 @@ TypeScriptForInOrOfStatementNode.prototype.validateTypeScriptGrammar = function return; const isUsing = initializerNode.keywordNode instanceof TypeScriptUsingKeywordNode; - if (initializerNode.children.length === 0 || !Object.isUndefined(initializerNode.getTypeScriptTrailingComma())) + const [declarationNode, secondDeclarationNode] = initializerNode.children; + if (Object.isUndefined(declarationNode) || !Object.isUndefined(initializerNode.getTypeScriptTrailingComma())) return; if (isUsing && !isForOf) { const template = Object.isUndefined(initializerNode.awaitKeywordNode) @@ -58,7 +59,6 @@ TypeScriptForInOrOfStatementNode.prototype.validateTypeScriptGrammar = function if (!Object.isUndefined(initializerNode.awaitKeywordNode) && (context.isClassStaticBlock || !context.isAwaitContext)) return; - const secondDeclarationNode = initializerNode.children[1]; if (!Object.isUndefined(secondDeclarationNode)) { context.diagnosticCollector.addTypeScriptGrammarDiagnostic(context.source, isForOf ? TypeScriptDiagnosticTemplates.TS1188 : TypeScriptDiagnosticTemplates.TS1091, @@ -66,7 +66,6 @@ TypeScriptForInOrOfStatementNode.prototype.validateTypeScriptGrammar = function return; } - const declarationNode = initializerNode.children[0]!; if (!Object.isUndefined(declarationNode.initializerNode)) context.diagnosticCollector.addTypeScriptGrammarDiagnostic(context.source, isForOf ? TypeScriptDiagnosticTemplates.TS1190 : TypeScriptDiagnosticTemplates.TS1189, declarationNode.nameNode.span); diff --git a/src/parsers/noldova.context.parsers.typescript/tests/conformance/conformance-cases.test.ts b/src/parsers/noldova.context.parsers.typescript/tests/conformance/conformance-cases.test.ts index 85d6c9f8..58a8104d 100644 --- a/src/parsers/noldova.context.parsers.typescript/tests/conformance/conformance-cases.test.ts +++ b/src/parsers/noldova.context.parsers.typescript/tests/conformance/conformance-cases.test.ts @@ -28,7 +28,8 @@ export class ConformanceCasesTests { @TestMethod public matchesTheReferenceUnlessKnownToFail(casePath: string): void { const expectations = ConformanceExpectationsReader.load(); - const record = expectations.applicableRecords.get(casePath)!; + const record = expectations.applicableRecords.get(casePath); + Assert.isDefined(record, casePath); const verdict = new ConformanceCaseComparison(record, expectations.readUnits(record), ParserDiagnosticScope.load()).run(); const failure = KnownFailuresLedger.load().failing.get(casePath); From 2cb8febbac9cc56eb97c7b59f256c4f9eedc3f8e Mon Sep 17 00:00:00 2001 From: Rostislav Rotaru Date: Sat, 14 Nov 2026 17:38:39 -0800 Subject: [PATCH 2/3] Prove the related location the diagnostics fixture reads Agent: DEV1 (developer) Agent-Model: Anthropic Opus 5.5, Medium --- .../tests/fixtures/typescript-diagnostics.fixture.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/parsers/noldova.context.parsers.typescript/tests/fixtures/typescript-diagnostics.fixture.ts b/src/parsers/noldova.context.parsers.typescript/tests/fixtures/typescript-diagnostics.fixture.ts index 656763ce..a4bbbec8 100644 --- a/src/parsers/noldova.context.parsers.typescript/tests/fixtures/typescript-diagnostics.fixture.ts +++ b/src/parsers/noldova.context.parsers.typescript/tests/fixtures/typescript-diagnostics.fixture.ts @@ -6,7 +6,7 @@ * LICENSE file in the root directory of this source tree. */ -import type { Diagnostic } from "@noldova/context.diagnostics"; +import type { Diagnostic, DiagnosticRelatedInformation } from "@noldova/context.diagnostics"; import { TypeScriptParser } from "@noldova/context.parsers.typescript"; import { Assert } from "@noldova/context.testing"; @@ -33,7 +33,7 @@ export class TypeScriptDiagnosticsFixture { public static projectWithRelated(diagnostics: readonly Diagnostic[]): string { return diagnostics.map(t => TypeScriptDiagnosticsFixture.position(t) - + t.relatedInformation.map(related => `{${related.message.text}@${related.location!.start}}`).join(String.empty)) + + t.relatedInformation.map(related => TypeScriptDiagnosticsFixture.related(related)).join(String.empty)) .join(TypeScriptDiagnosticsFixture.SEPARATOR); } @@ -52,4 +52,10 @@ export class TypeScriptDiagnosticsFixture { Assert.isDefined(location); return content.slice(location.start, location.start + location.length); } + + private static related(related: DiagnosticRelatedInformation): string { + const location = related.location; + Assert.isDefined(location); + return `{${related.message.text}@${location.start}}`; + } } From e3dd4f7b72f977637a3d900799d6597539ce7461 Mon Sep 17 00:00:00 2001 From: Rostislav Rotaru Date: Sat, 14 Nov 2026 17:40:19 -0800 Subject: [PATCH 3/3] Read the type operator example's operand without a non-null assertion Agent: DEV1 (developer) Agent-Model: Anthropic Opus 5.5, Medium --- .../noldova.context.parsers.typescript/src/api/index.d.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/parsers/noldova.context.parsers.typescript/src/api/index.d.ts b/src/parsers/noldova.context.parsers.typescript/src/api/index.d.ts index 7b7bd88a..8cbedf1d 100644 --- a/src/parsers/noldova.context.parsers.typescript/src/api/index.d.ts +++ b/src/parsers/noldova.context.parsers.typescript/src/api/index.d.ts @@ -9023,7 +9023,8 @@ export declare class TypeScriptTypeLiteralNode extends CompositeNode { * const operand = new TypeScriptIdentifierNode("Value", new SourceSpan(1, 5)); * const operator = new TypeScriptQuestionNode(new SourceSpan(0, 1)); * const type = new TypeScriptTypeOperatorNode(operator, new SourceSpan(0, 6), operand); - * type.operatorNode.span.startOffset < type.typeNode!.span.startOffset; // prefix + * type.typeNode === operand; // true + * type.operatorNode.span.startOffset < operand.span.startOffset; // prefix * ``` */ export declare class TypeScriptTypeOperatorNode extends Node {