Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FileMustStartWithPackageStatement check #139

2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- Fix sslr-magik-toolkit's "Evaluate XPath"-button.
- Add UndefinedVariable check to Sonar way profile.
- Add ability to override aliases path and environment path in tasks in VSCode extension.
- Add FileWithoutPackageStatement check to test if a file starts with a `_package`-statement.
- Several fixes.

### Breaking changes (reiterated from above)
Expand All @@ -35,6 +36,7 @@
- Add SimplifyIf check to Sonar way profile. This might result in more issues.
- Add UnsafeEvaluateInvocation check to Sonar way profile. This might result in more issues.
- Add UndefinedVariable check to Sonar way profile. This might result in more issues.
- Add FileWithoutPackageStatement check to test if a file starts with a `_package`-statement. This might result in more issues.
StevenLooman marked this conversation as resolved.
Show resolved Hide resolved

## 0.10.1 (2024-08-14)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import nl.ramsolutions.sw.magik.checks.checks.ExemplarSlotCountCheck;
import nl.ramsolutions.sw.magik.checks.checks.FileMethodCountCheck;
import nl.ramsolutions.sw.magik.checks.checks.FileNotInLoadListCheck;
import nl.ramsolutions.sw.magik.checks.checks.FileWithoutPackageStatementCheck;
import nl.ramsolutions.sw.magik.checks.checks.ForbiddenCallCheck;
import nl.ramsolutions.sw.magik.checks.checks.ForbiddenGlobalUsageCheck;
import nl.ramsolutions.sw.magik.checks.checks.ForbiddenInheritanceCheck;
Expand Down Expand Up @@ -68,6 +69,7 @@ public static List<Class<? extends MagikCheck>> getChecks() {
ExemplarSlotCountCheck.class,
FileMethodCountCheck.class,
FileNotInLoadListCheck.class,
FileWithoutPackageStatementCheck.class,
ForbiddenCallCheck.class,
ForbiddenGlobalUsageCheck.class,
ForbiddenInheritanceCheck.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package nl.ramsolutions.sw.magik.checks.checks;

import com.sonar.sslr.api.AstNode;
import java.util.List;
import nl.ramsolutions.sw.magik.api.MagikGrammar;
import nl.ramsolutions.sw.magik.checks.MagikCheck;
import org.sonar.check.Rule;

/** Check if file starts with a _package-statement. */
@Rule(key = FileWithoutPackageStatementCheck.CHECK_KEY)
public class FileWithoutPackageStatementCheck extends MagikCheck {

@SuppressWarnings("checkstyle:JavadocVariable")
public static final String CHECK_KEY = "FileWithoutPackageStatement";

private static final String MESSAGE = "File has no package-statement.";

@Override
protected void walkPostMagik(final AstNode node) {
if (!this.hasPackageStatement(node)) {
this.addFileIssue(MESSAGE);
}
}

private boolean hasPackageStatement(final AstNode node) {
final List<AstNode> children = node.getChildren();
if (children.isEmpty()) {
return false;
}

return children.get(0).is(MagikGrammar.PACKAGE_SPECIFICATION);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<p>File should start with a <code>_package</code>-statement. This ensures the code is loaded into the correct package.</p>
<h2>Noncompliant Code Example</h2>
<pre>
_block
write(a)
_endblock
</pre>
<h2>Compliant Solution</h2>
<pre>
_package user

_block
write(a)
_endblock
</pre>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"title": "File should start with a package-statement",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"bad-practice",
"confusing"
],
"defaultSeverity": "Minor",
"ruleSpecification": "FileWithoutPackageStatement",
sebastiaanspeck marked this conversation as resolved.
Show resolved Hide resolved
"sqKey": "file-without-package-statement"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"EmptyBlock",
"ExemplarSlotCount",
"FileNotInLoadList",
"FileWithoutPackageStatement",
"ForbiddenCall",
"ForbiddenGlobalUsage",
"HidesVariable",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package nl.ramsolutions.sw.magik.checks.checks;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import nl.ramsolutions.sw.magik.checks.MagikIssue;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

/** Test FileWithoutPackageStatementCheck. */
class FileWithoutPackageStatementCheckTest extends MagikCheckTestBase {

@ParameterizedTest
@ValueSource(
strings = {
"""
_package user

_method a.m1 _endmethod
""",
"""
# This is just a comment
_package user

_method a.m1 _endmethod
""",
})
void testValid(final String code) {
final FileWithoutPackageStatementCheck check = new FileWithoutPackageStatementCheck();
final List<MagikIssue> issues = this.runCheck(code, check);
assertThat(issues).isEmpty();
}

@ParameterizedTest
@ValueSource(
strings = {
"""
_method a.m1 _endmethod
""",
"""
_method a.m1 _endmethod

_package user

_method a.m2 _endmethod
""",
})
void testInvalid(final String code) {
final FileWithoutPackageStatementCheck check = new FileWithoutPackageStatementCheck();
final List<MagikIssue> issues = this.runCheck(code, check);
assertThat(issues).hasSize(1);
}
}
Loading