Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 49 additions & 6 deletions src/main/java/org/eolang/lints/LtAsciiOnly.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
/**
* A comment must include only ASCII characters.
* @since 0.1.0
* @todo #14:35min Calculate comment line number with abusive character.
Comment thread
VasilevNStas marked this conversation as resolved.
* For now we just reusing object line number (via @line), which is not correct
* for specifying on which line of the program comment is located. This issue
* can be solved after <a href="https://github.com/objectionary/eo/issues/3536">this one</a>.
* @todo #402:15min Replace the creation of new ArrayList<>(0) with the creation of
* ArrayList<>() without a constructor argument in whole project. Add ignore warning
* ConditionalRegexpMultilineCheck from Checkstyle (it doesn't seem to be possible at the moment
Expand All @@ -32,6 +28,8 @@ final class LtAsciiOnly implements Lint {
public Collection<Defect> defects(final XML xmir) throws IOException {
final Collection<Defect> defects = new ArrayList<>(0);
final Xnav xml = new Xnav(xmir.inner());
final Optional<String> listing = xml.path("//listing")
.findFirst().map(elem -> elem.text().get());
final List<Xnav> comments = xml.path("/object/comments/comment")
.collect(Collectors.toList());
for (final Xnav comment : comments) {
Expand All @@ -42,8 +40,23 @@ public Collection<Defect> defects(final XML xmir) throws IOException {
if (!abusive.isPresent()) {
continue;
}
final int line = new LineOf(comment).value();
final Character chr = abusive.get();
final String text = comment.text().get();
final int pos = text.indexOf(chr);
final int line;
if (listing.isPresent()) {
final Optional<Integer> found = LtAsciiOnly.locate(
listing.get(), text
);
if (found.isPresent()) {
line = found.get() + (int) text.substring(0, pos).chars()
.filter(c -> c == '\n').count();
} else {
line = new LineOf(comment).value();
}
} else {
line = new LineOf(comment).value();
}
defects.add(
new Defect.Default(
"ascii-only",
Expand All @@ -53,7 +66,7 @@ public Collection<Defect> defects(final XML xmir) throws IOException {
"Only ASCII characters are allowed in comments, while \"%s\" is used at the line no.%s at the position no.%s",
chr,
line,
comment.text().get().indexOf(chr) + 1
pos + 1
)
)
);
Expand All @@ -75,4 +88,34 @@ public String motive() throws IOException {
public Fix fix() {
return new FxEmpty();
}

/**
* Real source line of the abusive character.
* The comment text is located in the program listing, where each line
* starts with the {@code #} sign. The line of the character is the line
* of the first line of the comment.
* @param listing Full program listing
* @param text Comment text
* @return Real source line of the first line of the comment, if found
*/
private static Optional<Integer> locate(final String listing, final String text) {
final int newline = text.indexOf('\n');
final String headline;
if (newline < 0) {
headline = text;
} else {
headline = text.substring(0, newline);
}
final int index = listing.indexOf("# ".concat(headline));
final Optional<Integer> result;
if (index < 0) {
result = Optional.empty();
} else {
result = Optional.of(
(int) listing.substring(0, index).chars()
.filter(chr -> chr == '\n').count() + 1
);
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@
</xsl:function>
<xsl:template match="/">
<defects>
<!--
A void attribute written as "? &gt;&gt; name" is skipped for the same
reason: its auto-name is minted by the parser, while "name" is only a
local alias. There is no nameless void in the grammar, so the "&gt;&gt;"
cannot be deleted, and the only other spelling, "? &gt; name", publishes
the attribute under that name and thus changes dispatch. See #1266.
-->
<xsl:for-each select="//o[@name and matches(@name, '^a🌵[0-9]+-[0-9]+$') and not(@base='∅') and not(eo:const-wrapper(.))]">
<xsl:variable name="refs" select="key('referenced-by-auto-name', @name)"/>
<xsl:variable name="external" select="$refs except descendant::o"/>
Expand Down
13 changes: 0 additions & 13 deletions src/main/resources/org/eolang/motives/misc/redundant-attachment.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,3 @@ written in the source, is left alone too. The `!` suffix on a nameless
argument is such a case: `m.plus m!` makes the parser wrap `m` into a named
`.as-bytes` over `Φ.dataized`, and no `>>` exists in the source to be
removed.

A void attribute declared as `? >> name` is left alone as well. The name
after `>>` is only a local alias, while the published name is generated by
the parser. The `>>` cannot be dropped, because the grammar has no nameless
void, and switching to `? > name` would publish the attribute under `name`
and change dispatch:

```eo
[] > choice
? >> left
? >> right
left > @
```
26 changes: 26 additions & 0 deletions src/test/java/org/eolang/lints/LtAsciiOnlyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,30 @@ void doesNotFlagNewlinesInMultilineComment() throws IOException {
Matchers.emptyIterable()
);
}

@Test
void reportsCorrectLineInMultilineComment() throws IOException {
MatcherAssert.assertThat(
"The abusive character is on the second line of the comment",
new ListOf<>(
new LtAsciiOnly().defects(
new EoProgram("org/eolang/lints/non-ascii-multiline.eo").parse()
)
).get(0).line(),
Matchers.equalTo(2)
);
}

@Test
void reportsCorrectLineInTheMiddle() throws IOException {
MatcherAssert.assertThat(
"The abusive character is on the second line of a three-line comment",
new ListOf<>(
new LtAsciiOnly().defects(
new EoProgram("org/eolang/lints/non-ascii-middle.eo").parse()
)
).get(0).line(),
Matchers.equalTo(2)
);
}
}
8 changes: 8 additions & 0 deletions src/test/resources/org/eolang/lints/non-ascii-middle.eo
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# first
Comment thread
VasilevNStas marked this conversation as resolved.
# привет middle
# last

+spdx SPDX-FileCopyrightText: Copyright (c) 2016-2026 Objectionary.com
+spdx SPDX-License-Identifier: MIT

[] > foo
7 changes: 7 additions & 0 deletions src/test/resources/org/eolang/lints/non-ascii-multiline.eo
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This comment is fine
# but here привет

+spdx SPDX-FileCopyrightText: Copyright (c) 2016-2026 Objectionary.com
+spdx SPDX-License-Identifier: MIT

[] > foo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

+spdx SPDX-FileCopyrightText: Copyright (c) 2016-2026 Objectionary.com
+spdx SPDX-License-Identifier: MIT
+unlint ascii-only:3
+unlint ascii-only:1

[] > hello
Loading