Skip to content

Add parseDotInt#24

Merged
IvanGoncharov merged 1 commit into
mainfrom
pr_branch
May 26, 2026
Merged

Add parseDotInt#24
IvanGoncharov merged 1 commit into
mainfrom
pr_branch

Conversation

@IvanGoncharov

Copy link
Copy Markdown
Member

No description provided.

Copilot AI review requested due to automatic review settings May 17, 2026 22:18

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the workflow documentation in AGENTS.md and introduces a new utility function, parseDotInt, to handle integer parsing for Graphviz attributes. In src/viz.ts, the linelength attribute parsing was updated to use this new utility. Feedback identifies that the parseDotInt regex incorrectly allows decimal values, which contradicts its intended use for strict integers. Furthermore, a regression was noted in src/viz.ts where the validation check was weakened from Number.isInteger to Number.isNaN, potentially allowing invalid non-integer values to be accepted.

Comment thread src/utils.ts Outdated
Comment thread src/viz.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a new utility helper (parseDotInt) and switches Viz’s linelength attribute parsing to use it, aiming to validate numeric DOT attribute values more strictly/consistently.

Changes:

  • Import and use parseDotInt when parsing linelength in src/viz.ts.
  • Add parseDotInt (with a numeric regex gate) to src/utils.ts.
  • Strengthen workflow instructions in AGENTS.md.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/viz.ts Uses parseDotInt for linelength parsing and adjusts validation logic.
src/utils.ts Adds parseDotInt and a regex intended to constrain numeric parsing.
AGENTS.md Adds a “mandatory workflow” emphasis note to agent guidelines.
Comments suppressed due to low confidence (1)

src/viz.ts:265

  • The new linelength validation no longer enforces that the parsed value is an integer: isMaxLineLength only range-checks, so values like 60.5 will pass and be forwarded to the backend even though the error message (and existing behavior) says linelength must be an integer. Keep an explicit integer check here (or make parseDotInt reject non-integer forms such as 60.0/60.5) before accepting the value.
      const number = NormalizedAttributes.isText(linelengthValue)
        ? parseDotInt(linelengthValue.text)
        : Number.NaN;
      if (Number.isNaN(number) || !isMaxLineLength(number)) {
        return failureResult([

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils.ts Outdated
Comment thread src/viz.ts Outdated
@IvanGoncharov

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the workflow documentation in AGENTS.md to emphasize that all steps are mandatory and introduces a parseDotNumber utility in src/utils.ts for parsing Graphviz numeric attributes. The utility is integrated into src/viz.ts to handle the linelength attribute. Feedback was provided regarding the parseDotNumber regex, which currently fails to account for valid DOT numerals with leading or trailing decimal points, along with a suggestion to align the implementation with the Graphviz specification.

Comment thread src/utils.ts Outdated
Comment on lines +9 to +12
const DOT_NUMBER_RE = /^-?\d+(\.\d+)?$/;
export function parseDotNumber(value: string): number {
return DOT_NUMBER_RE.test(value) ? Number(value) : Number.NaN;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The implementation name parseDotNumber and its support for decimal points in the regex contradict the pull request title Add parseDotInt.

Furthermore, the regex /^-?\d+(\.\d+)?$/ does not account for all valid DOT numerals. According to the Graphviz specification, a numeral can have a leading or trailing decimal point (e.g., .5 or 5.).

If this function is intended to be a general-purpose DOT numeral parser, I recommend updating the regex to be spec-compliant. If it is specifically for integers, it should be renamed to parseDotInt and the regex simplified to /^-?\d+$/.

Suggested change
const DOT_NUMBER_RE = /^-?\d+(\.\d+)?$/;
export function parseDotNumber(value: string): number {
return DOT_NUMBER_RE.test(value) ? Number(value) : Number.NaN;
}
const DOT_NUMBER_RE = /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;
export function parseDotNumber(value: string): number {
return DOT_NUMBER_RE.test(value) ? Number(value) : Number.NaN;
}

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread src/utils.ts Outdated
@IvanGoncharov

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the workflow documentation to emphasize mandatory steps and introduces a parseDotNumber utility for more robust parsing of Graphviz attributes. A critical logic error was identified in the regular expression used for number parsing, which could allow partial matches and invalid strings to be accepted; a fix was suggested to correctly group the alternation and support trailing decimal points.

Comment thread src/utils.ts Outdated
.slice(1, -1);
}

const DOT_NUMBER_RE = /^-?\d+(\.\d+)?|-?\.\d+$/;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The DOT_NUMBER_RE regular expression has a logic error because the alternation (|) is not grouped, causing the anchors (^ and $) to only apply to one side of the OR. This allows partial matches (e.g., "123abc" or "abc.123") to pass the test. Additionally, to align with the project's parser and the Graphviz specification, it should support trailing decimal points like 123.. Note that while the PR title mentions parseDotInt, this implementation correctly provides a more general parseDotNumber utility.

Suggested change
const DOT_NUMBER_RE = /^-?\d+(\.\d+)?|-?\.\d+$/;
const DOT_NUMBER_RE = /^-?(\.\d+|\d+(\.\d*)?)$/;

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/utils.ts:12

  • The PR title suggests adding parseDotInt, but this change introduces parseDotNumber and uses it for linelength (an integer-only attribute). If the intent is specifically integer parsing/validation, consider renaming to parseDotInt (or adding a dedicated parseDotInt wrapper) to match the stated goal and make call sites clearer.
const DOT_NUMBER_RE = /^-?\d+(\.\d+)?|-?\.\d+$/;
export function parseDotNumber(value: string): number {
  return DOT_NUMBER_RE.test(value) ? Number(value) : Number.NaN;
}

Comment thread src/utils.ts Outdated
Comment thread src/viz.ts
@IvanGoncharov

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the workflow documentation in AGENTS.md, introduces a parseDotNumber utility for DOT-specific number parsing, and applies it to linelength validation in Viz. It also moves ESLint directives within parser.ts and expands test coverage for invalid linelength values. Review feedback identifies that the new regex for number parsing fails to account for valid trailing decimal points and suggests that moving the ESLint directives into individual methods creates redundancy and inconsistency.

Comment thread src/utils.ts Outdated
Comment thread src/parser.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

src/parser.ts:171

  • Same as above: this /* eslint-disable unicorn/prefer-code-point */ directive is not scoped to the method and will keep the rule disabled beyond this point unless explicitly re-enabled. Prefer eslint-disable-next-line on the charCodeAt statement or re-enable immediately after.
  #peekChar(): number {
    // To make parser internally consistent, all characters are read as UTF-16:
    /* eslint-disable unicorn/prefer-code-point */
    return this.#dotStr.charCodeAt(this.#nextIndex);

Comment thread test/render.test.ts
Comment thread src/parser.ts
Comment thread src/utils.ts Outdated
@IvanGoncharov

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the workflow guidelines in AGENTS.md, refactors ESLint disable comments in src/parser.ts, and introduces a parseDotNumber utility to safely parse numeric values from DOT attributes, accompanied by expanded test coverage for invalid linelength values. The reviewer feedback suggests keeping the file-level ESLint disable comment to avoid repetitive method-level disables, and moving parseDotNumber to src/parser.ts to prevent a circular dependency between src/parser.ts and src/utils.ts.

Comment thread src/parser.ts
Comment on lines 11 to 12

// To make parser internally consistent, all characters are read as UTF-16:
/* eslint-disable unicorn/prefer-code-point */

const Char = {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Restoring the file-level eslint-disable comment is cleaner and avoids ESLint errors in other methods like #peekAheadChar which also use charCodeAt but were missed in this PR.

Suggested change
// To make parser internally consistent, all characters are read as UTF-16:
/* eslint-disable unicorn/prefer-code-point */
const Char = {
// To make parser internally consistent, all characters are read as UTF-16:
/* eslint-disable unicorn/prefer-code-point */
const Char = {

Comment thread src/parser.ts
Comment on lines 162 to 172
#readChar(): number {
// To make parser internally consistent, all characters are read as UTF-16:
/* eslint-disable unicorn/prefer-code-point */
return this.#dotStr.charCodeAt(this.#nextIndex++);
}

#peekChar(): number {
// To make parser internally consistent, all characters are read as UTF-16:
/* eslint-disable unicorn/prefer-code-point */
return this.#dotStr.charCodeAt(this.#nextIndex);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

With the file-level eslint-disable restored, these repetitive method-level disables can be removed.

  #readChar(): number {
    return this.#dotStr.charCodeAt(this.#nextIndex++);
  }

  #peekChar(): number {
    return this.#dotStr.charCodeAt(this.#nextIndex);
  }

Comment thread src/parser.ts
Comment on lines +1111 to +1115
export function isNumberToken(str: string): boolean {
const lexer = new Lexer(str);
const token = lexer.nextToken();
return token.kind === Kind.Number && token.length === str.length;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Moving parseDotNumber to src/parser.ts next to isNumberToken avoids a circular dependency between src/parser.ts and src/utils.ts.

Suggested change
export function isNumberToken(str: string): boolean {
const lexer = new Lexer(str);
const token = lexer.nextToken();
return token.kind === Kind.Number && token.length === str.length;
}
export function isNumberToken(str: string): boolean {
const lexer = new Lexer(str);
const token = lexer.nextToken();
return token.kind === Kind.Number && token.length === str.length;
}
export function parseDotNumber(value: NormalizedAttributeValue): number {
return NormalizedAttributes.isText(value) && isNumberToken(value.text)
? Number.parseFloat(value.text)
: Number.NaN;
}

Comment thread src/utils.ts
Comment on lines +1 to +5
import {
NormalizedAttributes,
type NormalizedAttributeValue,
} from './normalize-graph.ts';
import { isNumberToken } from './parser.ts';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

These imports are no longer needed once parseDotNumber is moved to src/parser.ts.

Comment thread src/utils.ts
Comment on lines +15 to +19
export function parseDotNumber(value: NormalizedAttributeValue): number {
return NormalizedAttributes.isText(value) && isNumberToken(value.text)
? Number.parseFloat(value.text)
: Number.NaN;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Removing parseDotNumber from src/utils.ts as it has been moved to src/parser.ts to resolve the circular dependency.

Comment thread src/viz.ts
Comment on lines 8 to +9
import { parseDot } from './parser.ts';
import { formatValueForDiagnostics } from './utils.ts';
import { formatValueForDiagnostics, parseDotNumber } from './utils.ts';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Import parseDotNumber from ./parser.ts instead of ./utils.ts to align with the move and avoid circular dependencies.

Suggested change
import { parseDot } from './parser.ts';
import { formatValueForDiagnostics } from './utils.ts';
import { formatValueForDiagnostics, parseDotNumber } from './utils.ts';
import { parseDot, parseDotNumber } from './parser.ts';
import { formatValueForDiagnostics } from './utils.ts';

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Comment thread src/parser.ts

#readChar(): number {
// To make parser internally consistent, all characters are read as UTF-16:
/* eslint-disable unicorn/prefer-code-point */
Comment thread src/parser.ts
Comment on lines +164 to +170
/* eslint-disable unicorn/prefer-code-point */
return this.#dotStr.charCodeAt(this.#nextIndex++);
}

#peekChar(): number {
// To make parser internally consistent, all characters are read as UTF-16:
/* eslint-disable unicorn/prefer-code-point */
Comment thread src/utils.ts
@IvanGoncharov IvanGoncharov merged commit 428e3b8 into main May 26, 2026
2 checks passed
@IvanGoncharov IvanGoncharov deleted the pr_branch branch May 26, 2026 22:57
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.

2 participants