Skip to content

Feature(#797): add +syntax in meta#798

Open
Daniilmipt wants to merge 10 commits intoobjectionary:masterfrom
Daniilmipt:feature(#797)
Open

Feature(#797): add +syntax in meta#798
Daniilmipt wants to merge 10 commits intoobjectionary:masterfrom
Daniilmipt:feature(#797)

Conversation

@Daniilmipt
Copy link

@Daniilmipt Daniilmipt commented Feb 15, 2026

We should compare parser version with version from meta +syntax and be sure to detect this meta "+syntax"

Summary by CodeRabbit

  • New Features

    • Added a lint that validates +syntax uses SemVer and flags when it’s newer than the parser.
  • Documentation

    • Added a motive describing syntax-version mismatches with examples.
    • Updated metadata docs to recognize +syntax as a supported meta.
  • Bug Fixes / Behavior

    • Treat +syntax as a known meta for duplicate/unknown checks.
  • Tests

    • Added tests for version comparisons, formats, defaults, and error cases.

@coderabbitai
Copy link

coderabbitai bot commented Feb 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new lint that validates +syntax SemVer and compares it to a configured parser version, marks syntax as a known meta in XSLT, adds motive documentation, and introduces tests covering valid, invalid, and edge-case behaviors.

Changes

Cohort / File(s) Summary
Syntax Version Lint Implementation
src/main/java/org/eolang/lints/LtSyntaxVersion.java
New final class implementing Lint<XML>: validates +syntax SemVer format, compares it to a constructor-provided parser version, emits defects with line numbers for invalid formats or when syntax version is newer; provides name() and motive().
XSLT Meta Configuration
src/main/resources/org/eolang/lints/metas/unique-metas.xsl, src/main/resources/org/eolang/lints/metas/unknown-metas.xsl
Added syntax to known/unique meta lists so +syntax is treated as a recognized meta and excluded from unknown-meta defects.
Motive Documentation
src/main/resources/org/eolang/motives/metas/syntax-version-mismatch.md
New motive explaining +syntax purpose, compatibility rules, examples of mismatches and correct usage.
Docs Update
src/main/resources/org/eolang/motives/metas/unknown-metas.md
Updated examples and list to include +syntax among known metas.
Tests
src/test/java/org/eolang/lints/LtSyntaxVersionTest.java
New tests covering: syntax newer than parser (defect), parser newer or equal (no defect), default parser version behavior, absence of +syntax, invalid SemVer formats, severity assertions, major/patch mismatch cases, and constructor validation (IllegalArgumentException for bad parser version).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

core

Suggested reviewers

  • yegor256
  • maxonfjvipon

Poem

🐰 I sniffed the metas, counted version hops,
If syntax outruns the parser, I sound the props.
Numbers must match, or I'll thump and say "No!"
A tiny lint rabbit keeping formats in tow. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ⚠️ Unable to check for merge conflicts: Invalid branch name format
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: adding support for the +syntax meta entry with version validation logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/main/java/org/eolang/lints/LtSyntaxVersion.java`:
- Around line 115-117: The validation method valid() accepts semver strings with
pre-release suffixes (e.g. "0.59.0-beta") while parts() strips the suffix before
numeric comparison, making "0.59.0-beta" compare equal to "0.59.0"; either
forbid pre-release suffixes in valid() or implement proper pre-release handling:
update valid() to not accept "-..." suffixes (remove the optional
"-[a-zA-Z0-9-]+" from the regex) if you want to treat only plain semver, or
modify parts() (and the comparison logic that uses parts()) to preserve and
return the pre-release token and add a pre-release comparator that enforces
SemVer precedence (pre-release < no pre-release, and lexicographic/numeric
ordering of dot-separated identifiers) so comparisons using parts()/the
comparator respect SemVer rules.
- Around line 47-49: The constructor LtSyntaxVersion(final String parserVersion)
must validate parserVersion (non-null, non-empty, and valid SemVer) to avoid
NumberFormatException later in parts(); add validation in the LtSyntaxVersion
constructor that checks parserVersion against a SemVer pattern (or attempts to
parse via the existing parts() helper) and throws an IllegalArgumentException
with a clear message (including the invalid value) if it fails; reference the
LtSyntaxVersion constructor, the parserVersion field and the parts() method when
implementing this defensive check.

In `@src/main/java/org/eolang/lints/MonoLints` copy.java:
- Around line 1-66: Remove the accidental duplicate source (the class named
MonoLints copy) and instead update the original MonoLints class to include the
new LtSyntaxVersion in its LINTS list; specifically, ensure MonoLints.LINTS
contains new LtAsciiOnly(), new LtReservedName(), new LtSyntaxVersion() (in that
list), and leave the rest of the constructor logic (LtIncorrectUnlint,
LtUnlintNonExistingDefect, WpaLints, WpaLintNames) unchanged so behavior and
mutual-ignore names are preserved.
🧹 Nitpick comments (1)
src/test/java/org/eolang/lints/LtSyntaxVersionTest.java (1)

107-131: Fragile: .iterator().next() can throw NoSuchElementException if defects is empty.

Both reportsErrorSeverityForInvalidFormat and reportsErrorSeverity directly call .iterator().next() on the defects collection. If the lint unexpectedly returns zero defects due to a bug, the test fails with a confusing NoSuchElementException rather than a meaningful assertion message.

Consider asserting the collection is non-empty first, or using Hamcrest's hasItem with a severity matcher to get a clear assertion failure.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/test/java/org/eolang/lints/LtSyntaxVersionTest.java`:
- Around line 160-174: The test method rejectsInvalidParserVersion calls
Assertions.assertThrows three times without explanation messages causing qulice
to fail; update the three assertThrows in
LtSyntaxVersionTest#rejectsInvalidParserVersion so each call to
Assertions.assertThrows provides a descriptive message (e.g., "should reject
'latest' version", "should reject empty version", "should reject null version"),
or alternatively annotate the test with
`@SuppressWarnings`("JTCOP.RuleAssertionMessage") if you prefer to silence the
rule; reference the test method name rejectsInvalidParserVersion and the
LtSyntaxVersion constructor when making the change.
🧹 Nitpick comments (2)
src/main/java/org/eolang/lints/LtSyntaxVersion.java (1)

153-160: Splitter import for a single trivial split — consider String.split instead.

Splitter.on('.').splitToList(...) pulls in Guava's Splitter for what version.split("-", 2)[0].split("\\.") achieves natively. Minor, but it's an extra dependency for no added safety here (the input is already validated).

src/test/java/org/eolang/lints/LtSyntaxVersionTest.java (1)

60-80: Two independent assertions in one test method.

usesDefaultVersionWhenNoArgCtor asserts two distinct behaviors (no defect for 0.0.0, one defect for 0.0.1). If the first assertion fails, the second is never reached. Consider splitting into two @Test methods for independent failure reporting.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/main/java/org/eolang/lints/LtSyntaxVersion.java`:
- Around line 149-164: The method newer() uses negative checks (major != 0 /
minor != 0) which triggers PMD's ConfusingTernary; update newer() to use
positive comparisons or early returns: compute left and right via
LtSyntaxVersion.parts(this.parser) and LtSyntaxVersion.parts(syntax), then
compare major, minor, patch using Integer.compare but branch with == 0 checks
(or return immediately when a comparison is non-zero) so the logic reads
positively (e.g., if (major == 0) { ... } else return major < 0), ensuring the
same boolean result while satisfying PMD.
🧹 Nitpick comments (1)
src/test/java/org/eolang/lints/LtSyntaxVersionTest.java (1)

66-86: Consider splitting two independent assertions into separate @Test methods.

usesDefaultVersionWhenNoArgCtor tests two distinct behaviors (no defect for 0.0.0 and one defect for 0.0.1). If the first assertion fails, the second is never executed. Splitting into two tests improves failure diagnostics.

@yegor256
Copy link
Member

@Daniilmipt the implementation looks excellent, thanks! However, we don't use this new class in the MonoLints class: https://github.com/objectionary/lints/blob/master/src/main/java/org/eolang/lints/MonoLints.java Because of this, your lint is not going to be used. It simply exists in the code but doesn't participate in the linting process.

@Daniilmipt
Copy link
Author

@Daniilmipt the implementation looks excellent, thanks! However, we don't use this new class in the MonoLints class: https://github.com/objectionary/lints/blob/master/src/main/java/org/eolang/lints/MonoLints.java Because of this, your lint is not going to be used. It simply exists in the code but doesn't participate in the linting process.

Thanks! You are right. I added this. Can you tell me if there is instruction somewhere on how to run the linter locally using the example of .eo file? I want to visually test how it will work

I found how to run from the eoc repository, but it's not clear how to bind the linter locally

new LtAsciiOnly(),
new LtReservedName()
new LtReservedName(),
new LtSyntaxVersion()
Copy link
Member

Choose a reason for hiding this comment

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

@Daniilmipt this will set the version to 0.0.0, which is not what we need, right? Maybe, you can get current version of from Manifests.read("EO-Version").

@yegor256
Copy link
Member

@Daniilmipt read this: https://www.yegor256.com/2025/05/25/bug-driven-development.html Don't ask questions like this. Instead, report a new bug, complaining about the quality of our documentation.

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