Skip to content

refactor: change null-safe operator syntax from .? to ?.#496

Merged
lukaszlenart merged 3 commits intomainfrom
refactor/change-null-safe-operator-syntax
Nov 18, 2025
Merged

refactor: change null-safe operator syntax from .? to ?.#496
lukaszlenart merged 3 commits intomainfrom
refactor/change-null-safe-operator-syntax

Conversation

@lukaszlenart
Copy link
Copy Markdown
Collaborator

Summary

Changes the null-safe navigation operator syntax from .? to ?. to align with industry-standard syntax used by Kotlin, TypeScript, C#, and Groovy.

Motivation

The original implementation used .? (dot-question) to differentiate OGNL from other languages. However, using ?. (question-dot) provides better consistency across the programming ecosystem and a more familiar syntax for developers coming from other languages.

Changes

Grammar & Implementation

  • Updated JavaCC grammar token from < SAFE_DOT: ".?" > to < SAFE_DOT: "?." >
  • Updated ASTChain.java JavaDoc and toString() method to reflect new syntax
  • Updated grammar comments to reference ?. operator

Tests

All test files updated with new syntax:

  • NullSafeOperatorTest.java (~65 test expressions)
  • NullSafeIntegrationTest.java (integration tests)
  • NullSafeCompilationTest.java (compilation tests)
  • NullSafeCollectionTest.java (collection tests)

Documentation

  • Updated docs/NullSafeOperator.md (title, rationale, all examples)
  • Updated docs/LanguageGuide.md (null-safe operator section)
  • Revised rationale to emphasize language consistency over differentiation

Test Results

All 683 tests pass successfully with the new syntax:

Tests run: 683, Failures: 0, Errors: 0, Skipped: 0

Breaking Change

⚠️ This is a breaking change for users currently using the .? operator from PR #484

Users will need to update their OGNL expressions from .? to ?. when upgrading.

Before:

user.?profile.?address.?city

After:

user?.profile?.address?.city

Files Changed

8 files modified, 154 insertions(+), 154 deletions(-):

  • Grammar: ognl/src/main/javacc/ognl.jj
  • Implementation: ognl/src/main/java/ognl/ASTChain.java
  • Tests: 4 test files
  • Documentation: 2 markdown files

🤖 Generated with Claude Code

lukaszlenart and others added 3 commits November 18, 2025 15:55
Changes the null-safe navigation operator from ".?" to "?." to align
with industry-standard syntax used by Kotlin, TypeScript, C#, and Groovy.
This improves consistency across programming languages and provides a
more familiar syntax for developers coming from other ecosystems.

Updated components:
- Grammar definition in ognl.jj (token and production rules)
- ASTChain implementation (JavaDoc and toString method)
- All null-safe operator tests (4 test files)
- Documentation (NullSafeOperator.md and LanguageGuide.md)
- Updated rationale to emphasize language consistency

All 683 tests pass with the new syntax.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Extracted nested condition into shouldAppendNavigationOperator() helper
method to reduce cognitive complexity from 17 to below the threshold of 15.

This addresses the SonarCloud code smell (java:S3776) by improving code
readability and reducing the nesting level in the toString() method.

Changes:
- Extract complex condition into private helper method
- Simplify nested if statement with single condition check
- Maintain identical behavior while improving maintainability

All 683 tests pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Added comprehensive SonarCloud documentation including:
- Project key and URLs
- How to view PR-specific issues
- Available MCP tools for SonarCloud integration
- Common SonarCloud rules encountered in OGNL
- Best practices for addressing quality issues

This helps future development by providing clear guidance on:
1. Using SonarQube MCP tools to fetch and address issues
2. Understanding common code smells specific to this project
3. Following quality gate requirements for PRs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
69.2% Coverage on New Code (required ≥ 80%)
E Maintainability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@lukaszlenart lukaszlenart added this to the 3.5.0 milestone Nov 18, 2025
@lukaszlenart lukaszlenart merged commit 392aa96 into main Nov 18, 2025
4 of 5 checks passed
@lukaszlenart lukaszlenart deleted the refactor/change-null-safe-operator-syntax branch November 18, 2025 15:35
lukaszlenart added a commit that referenced this pull request Nov 18, 2025
Add SAFE_DOT token and modify navigationChain production rule
to support null-safe navigation syntax (user?.profile?.city).

The parser now recognizes the ?. operator and sets a nullSafe
flag on ASTChain nodes, enabling null-safe property navigation
that returns null instead of throwing exceptions when encountering
null intermediate values.

Ported from main branch PRs #484 and #496.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
lukaszlenart added a commit that referenced this pull request Nov 18, 2025
Add nullSafe field and null-checking logic in getValueBody().
Returns null when encountering null intermediate values instead
of throwing exceptions.

Update toString() to output ?. operator when nullSafe flag is set.
Add helper method shouldAppendNavigationOperator() to reduce
cognitive complexity.

This enables expressions like:
- user?.profile?.city (returns null if any part is null)
- items?.{? #this > 0} (null-safe collection operations)
- #var?.method() (null-safe method calls)

Ported from main branch PRs #484 and #496, adapted for Java 8
compatibility (ognl-3-4-x branch).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
lukaszlenart added a commit that referenced this pull request Nov 29, 2025
…#497)

* feat(parser): add null-safe navigation operator (?.) token support

Add SAFE_DOT token and modify navigationChain production rule
to support null-safe navigation syntax (user?.profile?.city).

The parser now recognizes the ?. operator and sets a nullSafe
flag on ASTChain nodes, enabling null-safe property navigation
that returns null instead of throwing exceptions when encountering
null intermediate values.

Ported from main branch PRs #484 and #496.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* feat(core): implement null-safe operator logic in ASTChain

Add nullSafe field and null-checking logic in getValueBody().
Returns null when encountering null intermediate values instead
of throwing exceptions.

Update toString() to output ?. operator when nullSafe flag is set.
Add helper method shouldAppendNavigationOperator() to reduce
cognitive complexity.

This enables expressions like:
- user?.profile?.city (returns null if any part is null)
- items?.{? #this > 0} (null-safe collection operations)
- #var?.method() (null-safe method calls)

Ported from main branch PRs #484 and #496, adapted for Java 8
compatibility (ognl-3-4-x branch).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

---------

Co-authored-by: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant