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> {
Copy link
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
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
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());
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(
"<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()
);
}

@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")
);
}

@Test
void namesStableId() {
final LtRedundantHat lint = new LtRedundantHat();
MatcherAssert.assertThat(
"Rule id must be 'redundant-hat'",
lint.name(),
Matchers.equalTo("redundant-hat")
);
}
}
Loading