Skip to content

Type a field read through self, this or a parameter for integer division [patch] - #435

Open
matt-edmondson wants to merge 2 commits into
mainfrom
fix/433-dotted-field-integer-division
Open

matt-edmondson wants to merge 2 commits into
mainfrom
fix/433-dotted-field-integer-division

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

StandardLanguageGenerator.StaticType matched a VariableReference against declared field names whole, so self.total, this.total and p.total were of unknown type. IsIntegerArithmetic then returned false and integer / and % fell back to Python's and JavaScript's own operators: an int method returned -3.5, and Python's % floored to 1.

Change

StaticType now tries DottedMemberType before DeclaredMemberType:

  • The first segment is resolved from the function/accessor scopes (a parameter or local), or, when it is self/this and no scope declares it, as the class the body belongs to. Each StaticTypeScope now records its enclosing class.
  • Each later segment is looked up among the FieldDeclaration/member VariableDeclarations of exactly one class with the previous segment's type. This is the same rule DeclaredMethod uses for b.size() (Python and JavaScript still use true division on a method call with a receiver: b.size() / 2 gives -3.5 where C# gives -3 #280). An ambiguous class, a missing field, or an undeclared receiver keeps the type unknown, which is how it behaved before.

Testing

  • New DottedFieldIntegerDivisionTests runs the generated Python (python3) and JavaScript (node) for the issue's repro. It covers /, %, /= and %= through self./this. and through a typed parameter, and expects -3/-1 everywhere. A third test checks that an unknown field or receiver still emits plain /.
  • With the generator change reverted, both runtime tests fail (selfHalf = -3.5). With the change, they pass.
  • Full suite: 1555 passed, 0 failed.

Fixes #433


Generated by Claude Code

…ion [patch]

StaticType matched a VariableReference against field names whole, so
self.total, this.total and p.total were of unknown type and integer /
and % on them fell back to Python's and JavaScript's native operators:
an int method returned -3.5, and Python's % floored to 1.

Split a dotted name: resolve the first segment from the scopes, or as
the enclosing class when it is self or this, then look each later
segment up among the fields of exactly one class of the type before it,
the rule DeclaredMethod keeps for a call on a receiver.

Fixes #433

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW58QziM82v4d5H53oq
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW58QziM82v4d5H53oq
@sonarqubecloud

sonarqubecloud Bot commented Nov 1, 2026

Copy link
Copy Markdown

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.

Integer / and % on an instance field (self.total / 2, p.total % 2) use Python/JS native division: an int-typed method returns -3.5 instead of -3

2 participants