Skip to content
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0572bdf
add wrapper around FieldModifier for validation
sahilagichani14 Apr 18, 2025
a190f4b
added test for FieldModifiersValidator
sahilagichani14 Apr 18, 2025
9780fa6
Merge branch 'develop' into 794-check-for-valid-modifier-combinations
swissiety May 27, 2025
8f5848e
Merge branch 'develop' into 794-check-for-valid-modifier-combinations
sahilagichani14 May 30, 2025
0f81035
Merge branch 'develop' into 794-check-for-valid-modifier-combinations
sahilagichani14 May 30, 2025
26b2c4e
Merge branch 'develop' into 794-check-for-valid-modifier-combinations
sahilagichani14 Jun 3, 2025
eeee87a
Merge remote-tracking branch 'origin/794-check-for-valid-modifier-com…
sahilagichani14 Jun 3, 2025
f462e98
implement BodyValidationInterceptor, ClassValidationInterceptor
sahilagichani14 Jun 6, 2025
bafb3b2
missed method param
sahilagichani14 Jun 6, 2025
ac63486
implement InvokeArgumentValidator
sahilagichani14 Jun 10, 2025
b3ea18f
implement CheckEscapingValidator
sahilagichani14 Jun 11, 2025
7211837
implement CheckEscapingValidator
sahilagichani14 Jun 11, 2025
4732cc9
implement InvokeValidator
sahilagichani14 Jun 11, 2025
e769aa1
implement ReturnStatementsValidator
sahilagichani14 Jun 11, 2025
ab2f192
implement CheckTypesValidator && enable them by default
sahilagichani14 Jun 19, 2025
9ea4757
Merge branch 'develop' into 794-check-for-valid-modifier-combinations
sahilagichani14 Jun 19, 2025
4e4d842
fix license header failure && locale pkgName
sahilagichani14 Jun 19, 2025
e2048db
fix mvn com.spotify.fmt:fmt-maven-plugin:format
sahilagichani14 Jun 19, 2025
5e0184b
fix ClassValidationInterceptor
sahilagichani14 Jun 19, 2025
5cea9f1
disable bydefault validation interceptors
sahilagichani14 Jun 19, 2025
5bc5ed3
Merge branch 'develop' into 794-check-for-valid-modifier-combinations
sahilagichani14 Jul 8, 2025
1628711
Merge remote-tracking branch 'origin/develop' into 794-check-for-vali…
stschott Oct 22, 2025
4388eff
add test cases for validators
stschott Oct 23, 2025
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
12 changes: 2 additions & 10 deletions sootup.core/src/main/java/sootup/core/model/FieldModifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@
* #L%
*/

import java.util.EnumSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.jspecify.annotations.NonNull;

/**
* An Enum that provides static methods and constants to represent and work with with Java modifiers
* (ie public, final,...) Represents Java modifiers that can be packed and combined via EnumSet and
* An Enum that provides static methods and constants to represent and work with Java modifiers (ie
* public, final,...) Represents Java modifiers that can be packed and combined via EnumSet and
* methods to query these.
*/
public enum FieldModifier {
Expand Down Expand Up @@ -133,12 +131,6 @@ public static String toString(@NonNull Set<FieldModifier> m) {
return builder.toString();
}

@NonNull
// depends on the natural order of the Enums!
Comment thread
swissiety marked this conversation as resolved.
public static String toString(@NonNull EnumSet<FieldModifier> m) {
return m.stream().map((mod) -> mod.name().toLowerCase()).collect(Collectors.joining(" "));
}

/**
* @return the bytecode of this Modifier.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997-2020 Raja Vallée-Rai, Linghui Luo, Akshita Dubey
* Copyright (C) 1997-2020 Raja Vallée-Rai, Linghui Luo, Akshita Dubey, Sahil Agichani
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
Expand All @@ -22,13 +22,81 @@
* #L%
*/

import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import sootup.core.model.FieldModifier;
import sootup.core.model.SootClass;
import sootup.core.model.SootField;

/** Validator that checks for impossible combinations of field modifiers */
public class FieldModifiersValidator implements ClassValidator {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I reused this class, which was already there, or should I create another separate class for this wrapper?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is linked to #322
You can directly address the other validators as well.


private final EnumSet<FieldModifier> modifiers;

public FieldModifiersValidator(EnumSet<FieldModifier> modifiers) {
validate(modifiers);
this.modifiers = EnumSet.copyOf(modifiers);
}

public static FieldModifiersValidator of(FieldModifier... mods) {
if (mods == null || mods.length == 0) {
return new FieldModifiersValidator(EnumSet.noneOf(FieldModifier.class));

Check warning on line 45 in sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java#L45

Added line #L45 was not covered by tests
}
return new FieldModifiersValidator(EnumSet.copyOf(Arrays.asList(mods)));

Check warning on line 47 in sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java#L47

Added line #L47 was not covered by tests
}

public static FieldModifiersValidator from(Set<FieldModifier> mods) {
return new FieldModifiersValidator(EnumSet.copyOf(mods));

Check warning on line 51 in sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java#L51

Added line #L51 was not covered by tests
}

public Set<FieldModifier> asSet() {
return EnumSet.copyOf(modifiers);

Check warning on line 55 in sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java#L55

Added line #L55 was not covered by tests
}

public boolean contains(FieldModifier mod) {
return modifiers.contains(mod);

Check warning on line 59 in sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java#L59

Added line #L59 was not covered by tests
}

private void validate(EnumSet<FieldModifier> mods) {
long accessModifiers =
mods.stream()
.filter(
m ->
m == FieldModifier.PUBLIC
|| m == FieldModifier.PRIVATE
|| m == FieldModifier.PROTECTED)
.count();

if (accessModifiers > 1) {
throw new IllegalArgumentException("Only one of public, protected, private is allowed.");
}
// Add more rules here if needed
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder();

Check warning on line 80 in sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java#L80

Added line #L80 was not covered by tests

if (modifiers.contains(FieldModifier.PUBLIC)) builder.append("public ");
else if (modifiers.contains(FieldModifier.PRIVATE)) builder.append("private ");
else if (modifiers.contains(FieldModifier.PROTECTED)) builder.append("protected ");

if (modifiers.contains(FieldModifier.STATIC)) builder.append("static ");
if (modifiers.contains(FieldModifier.FINAL)) builder.append("final ");
if (modifiers.contains(FieldModifier.VOLATILE)) builder.append("volatile ");
if (modifiers.contains(FieldModifier.TRANSIENT)) builder.append("transient ");
if (modifiers.contains(FieldModifier.ENUM)) builder.append("enum ");
if (modifiers.contains(FieldModifier.SYNTHETIC)) builder.append("synthetic ");

if (!builder.isEmpty()) {
builder.setLength(builder.length() - 1); // remove trailing space

Check warning on line 94 in sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java#L94

Added line #L94 was not covered by tests
}

return builder.toString();

Check warning on line 97 in sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/validation/FieldModifiersValidator.java#L97

Added line #L97 was not covered by tests
}

@Override
public void validate(SootClass sc, List<ValidationException> exceptions) {
for (SootField sf : sc.getFields()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sootup.tests.validator;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.*;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -36,7 +37,7 @@ public class FieldModifiersValidatorTest {
@BeforeEach
public void setUp() {
view = new JavaView(Collections.singletonList(new EagerInputLocation()));
fieldModifiersValidator = new FieldModifiersValidator();
fieldModifiersValidator = new FieldModifiersValidator(EnumSet.noneOf(FieldModifier.class));
}

public JavaSootClass testClassCreatorWithModifiers(
Expand Down Expand Up @@ -139,6 +140,36 @@ public void testFieldModifiersValidator_fail1() {
assertEquals(1, validationExceptions_fail1.size());
}

@Test
void testInvalidAccessModifiers() {
IllegalArgumentException ex =
assertThrows(
IllegalArgumentException.class,
() -> FieldModifiersValidator.of(FieldModifier.PUBLIC, FieldModifier.PRIVATE));
assertEquals("Only one of public, protected, private is allowed.", ex.getMessage());
}

@Test
void testInvalidModifiers2() {
IllegalArgumentException ex =
assertThrows(
IllegalArgumentException.class,
() -> {
EnumSet<FieldModifier> invalidFieldModifiers =
EnumSet.of(FieldModifier.PRIVATE, FieldModifier.PROTECTED);
JavaSootField dummyField =
new JavaSootField(
new FieldSignature(
new JavaClassType("FieldModifiersValidator", PackageName.DEFAULT_PACKAGE),
"i",
PrimitiveType.IntType.getInstance()),
new FieldModifiersValidator(invalidFieldModifiers).asSet(),
Collections.emptyList(),
NoPositionInformation.getInstance());
});
assertEquals("Only one of public, protected, private is allowed.", ex.getMessage());
}

@Test
public void testFieldModifiersValidator_fail2() {
List<ValidationException> validationExceptions_fail1 = new ArrayList<>();
Expand Down