Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
60 changes: 60 additions & 0 deletions src/main/java/org/eolang/lints/LtRedundantHat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
* SPDX-License-Identifier: MIT
*/
package org.eolang.lints;

import com.github.lombrozo.xnav.Xnav;
import com.jcabi.xml.XML;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.eolang.parser.OnDefault;

/**
* Lint that warns if a redundant {@code ^} is used.
*
* @since 0.0.60
*/
final class LtRedundantHat implements Lint<XML> {
Comment thread
Snehakb1219-christ marked this conversation as resolved.
Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Snehakb1219-christ looks like we can implement this lint in XSL, there is no need to do it in Java, I believe

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@h1alexbel It works fine in java also. I think it's necessary to do this in XSL.
WDYT?

Copy link
Copy Markdown
Member

@h1alexbel h1alexbel Oct 14, 2025

Choose a reason for hiding this comment

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

@Snehakb1219-christ I believe that we should implement all lints in XSL. Java is for cases, where XSL won't work. Make sense?


@Override
public Collection<Defect> defects(final XML xmir) throws IOException {
final Collection<Defect> defects = new ArrayList<>(0);
final Xnav xml = new Xnav(xmir.inner());
final List<Xnav> objects = xml.path("//o[@base='^']").collect(Collectors.toList());
for (final Xnav object : objects) {
final String name = object.attribute("name").text().get();
final List<Xnav> parents = object.path(String.format("ancestor::o[.//o[@name='%s']]", name))
.collect(Collectors.toList());
Comment thread
Snehakb1219-christ marked this conversation as resolved.
if (parents.isEmpty()) {
defects.add(
new Defect.Default(
this.name(),
Severity.WARNING,
new OnDefault(xmir).get(),
Integer.parseInt(object.attribute("line").text().orElse("0")),
String.format(
"Redundant '^' notation: '%s' can be accessed without it",
name
)
)
);
}
}
return defects;
}

@Override
public String motive() throws IOException {
return "The '^' notation is used when there are no naming conflicts, please omitted for brevity.";
}

@Override
public String name() {
return "redundant-hat";
}
}

55 changes: 55 additions & 0 deletions src/test/java/org/eolang/lints/LtRedundantHatTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
* SPDX-License-Identifier: MIT
*/
package org.eolang.lints;

import com.jcabi.xml.XML;
import com.jcabi.xml.XMLDocument;
import java.io.IOException;
import java.util.Collection;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;

/**
* Test case for {@link LtRedundantHat}.
*
* @since 0.0.60
*/
final class LtRedundantHatTest {

@Test
void reportsNoDefectsForNecessaryHat() throws IOException {
final XML xml = new XMLDocument(
Comment thread
Snehakb1219-christ marked this conversation as resolved.
Outdated
"<program><object name='foo' line='10'><o name='+test' line='12'></o></object></program>"
);
final LtRedundantHat lint = new LtRedundantHat();
final Collection<Defect> defects = lint.defects(xml);
MatcherAssert.assertThat(
"Should not report a defect when '^' is necessary to resolve ambiguity",
defects,
Matchers.empty()
);
}
Comment thread
Snehakb1219-christ marked this conversation as resolved.
Outdated

@Test
void containsGuidanceInMotive() throws IOException {
final LtRedundantHat lint = new LtRedundantHat();
MatcherAssert.assertThat(
"Motive must explain when to omit redundant '^'",
lint.motive(),
Matchers.containsString("notation is used when there are no naming conflicts")
);
}
Comment thread
Snehakb1219-christ marked this conversation as resolved.
Outdated

@Test
void namesStableId() {
final LtRedundantHat lint = new LtRedundantHat();
Comment thread
Snehakb1219-christ marked this conversation as resolved.
Outdated
MatcherAssert.assertThat(
"Rule id must be 'redundant-hat'",
lint.name(),
Matchers.equalTo("redundant-hat")
);
}
}
Loading