Skip to content

Commit

Permalink
merged master
Browse files Browse the repository at this point in the history
  • Loading branch information
nimakarimipour committed Oct 29, 2024
2 parents d0bdaad + ac804c0 commit 8924cdc
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public RemoveAnnotation getReverse() {
@Nullable
public AddTypeUseMarkerAnnotation toDeclaration() {
// check if the annotation is on array declaration
// TODO check this for array.
if (isOnLocalVariableArray() && typeIndex.contains(ImmutableList.of(0))) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,20 @@ public Set<Modification> visit(ClassOrInterfaceType type, TypeUseAnnotationChang

@Override
public Set<Modification> visit(ArrayType type, TypeUseAnnotationChange change) {
return type.getComponentType().accept(this, change);
if (index.size() == 1 && index.getFirst() == 0) {
Modification onType = change.computeTextModificationOnType(type, annotationExpr);
if (onType != null) {
return Set.of(onType);
}
}
// if current index is 1, the process component type
if (!index.isEmpty()) {
boolean onComponentType = index.pollFirst() == 1;
if (onComponentType) {
return type.getComponentType().accept(this, change);
}
}
return Collections.emptySet();
}

@Override
Expand Down
110 changes: 55 additions & 55 deletions injector/src/main/java/edu/ucr/cs/riple/injector/util/ASTUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ public static String extractCallableName(String signature) {
*/
public static boolean isTypeDeclarationOrAnonymousClass(Node node) {
return node instanceof ClassOrInterfaceDeclaration
|| node instanceof EnumDeclaration
|| node instanceof AnnotationDeclaration
|| (node instanceof ObjectCreationExpr
|| node instanceof EnumDeclaration
|| node instanceof AnnotationDeclaration
|| (node instanceof ObjectCreationExpr
&& ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent());
}

Expand All @@ -112,7 +112,7 @@ public static boolean isTypeDeclarationOrAnonymousClass(Node node) {
* @throws TargetClassNotFound if the target class is not found.
*/
public static NodeList<BodyDeclaration<?>> getTypeDeclarationMembersByFlatName(
CompilationUnit cu, String flatName) throws TargetClassNotFound {
CompilationUnit cu, String flatName) throws TargetClassNotFound {
String packageName;
Optional<PackageDeclaration> packageDeclaration = cu.getPackageDeclaration();
if (packageDeclaration.isPresent()) {
Expand All @@ -121,13 +121,13 @@ public static NodeList<BodyDeclaration<?>> getTypeDeclarationMembersByFlatName(
packageName = "";
}
Preconditions.checkArgument(
flatName.startsWith(packageName),
"Package name of compilation unit is incompatible with class name: "
+ packageName
+ " : "
+ flatName);
flatName.startsWith(packageName),
"Package name of compilation unit is incompatible with class name: "
+ packageName
+ " : "
+ flatName);
String flatNameExcludingPackageName =
packageName.isEmpty() ? flatName : flatName.substring(packageName.length() + 1);
packageName.isEmpty() ? flatName : flatName.substring(packageName.length() + 1);
List<String> keys = new ArrayList<>(Arrays.asList(flatNameExcludingPackageName.split("\\$")));
Node cursor = findTopLevelClassDeclarationOnCompilationUnit(cu, keys.get(0));
keys.remove(0);
Expand All @@ -140,9 +140,9 @@ public static NodeList<BodyDeclaration<?>> getTypeDeclarationMembersByFlatName(
cursor = findAnonymousClassOrEnumConstant(cursor, index);
} else {
cursor =
indexString.isEmpty()
? findDirectInnerClass(cursor, actualName)
: findNonDirectInnerClass(cursor, actualName, index);
indexString.isEmpty()
? findDirectInnerClass(cursor, actualName)
: findNonDirectInnerClass(cursor, actualName, index);
}
}
return getMembersOfNode(cursor);
Expand All @@ -159,7 +159,7 @@ public static NodeList<BodyDeclaration<?>> getTypeDeclarationMembersByFlatName(
*/
@Nullable
public static VariableDeclarationExpr locateVariableDeclarationExpr(
CallableDeclaration<?> encMethod, String varName) {
CallableDeclaration<?> encMethod, String varName) {
// Should not visit inner nodes of inner methods in the given method, since the given
// method should be the closest enclosing method of the target local variable. Therefore, we
// use DirectMethodParentIterator to skip inner methods.
Expand All @@ -169,7 +169,7 @@ public static VariableDeclarationExpr locateVariableDeclarationExpr(
if (n instanceof VariableDeclarationExpr) {
VariableDeclarationExpr v = (VariableDeclarationExpr) n;
if (v.getVariables().stream()
.anyMatch(variableDeclarator -> variableDeclarator.getNameAsString().equals(varName))) {
.anyMatch(variableDeclarator -> variableDeclarator.getNameAsString().equals(varName))) {
return v;
}
}
Expand Down Expand Up @@ -251,14 +251,14 @@ public static String getPackageName(String name) {
* @return the static initializer blocks of the body declaration.
*/
public static Set<InitializerDeclaration> getStaticInitializerBlocks(
BodyDeclaration<?> bodyDeclaration) {
BodyDeclaration<?> bodyDeclaration) {
return bodyDeclaration.getChildNodes().stream()
.filter(
node ->
node instanceof InitializerDeclaration
&& ((InitializerDeclaration) node).isStatic())
.map(node -> (InitializerDeclaration) node)
.collect(Collectors.toSet());
.filter(
node ->
node instanceof InitializerDeclaration
&& ((InitializerDeclaration) node).isStatic())
.map(node -> (InitializerDeclaration) node)
.collect(Collectors.toSet());
}

/**
Expand All @@ -273,7 +273,7 @@ public static Set<InitializerDeclaration> getStaticInitializerBlocks(
*/
@Nonnull
private static TypeDeclaration<?> findTopLevelClassDeclarationOnCompilationUnit(
CompilationUnit tree, String name) throws TargetClassNotFound {
CompilationUnit tree, String name) throws TargetClassNotFound {
Optional<ClassOrInterfaceDeclaration> classDeclaration = tree.getClassByName(name);
if (classDeclaration.isPresent()) {
return classDeclaration.get();
Expand All @@ -283,7 +283,7 @@ private static TypeDeclaration<?> findTopLevelClassDeclarationOnCompilationUnit(
return enumDeclaration.get();
}
Optional<AnnotationDeclaration> annotationDeclaration =
tree.getAnnotationDeclarationByName(name);
tree.getAnnotationDeclarationByName(name);
if (annotationDeclaration.isPresent()) {
return annotationDeclaration.get();
}
Expand All @@ -309,12 +309,12 @@ private static TypeDeclaration<?> findTopLevelClassDeclarationOnCompilationUnit(
private static Node findDirectInnerClass(Node cursor, String name) throws TargetClassNotFound {
List<Node> nodes = new ArrayList<>();
cursor.walk(
Node.TreeTraversal.DIRECT_CHILDREN,
node -> {
if (isDeclarationWithName(node, name)) {
nodes.add(node);
}
});
Node.TreeTraversal.DIRECT_CHILDREN,
node -> {
if (isDeclarationWithName(node, name)) {
nodes.add(node);
}
});
if (nodes.isEmpty()) {
throw new TargetClassNotFound("Direct-Inner-Class", name, cursor);
}
Expand All @@ -331,15 +331,15 @@ private static Node findDirectInnerClass(Node cursor, String name) throws Target
* @throws TargetClassNotFound if the target class is not found.
*/
private static Node findNonDirectInnerClass(Node cursor, String name, int index)
throws TargetClassNotFound {
throws TargetClassNotFound {
final List<Node> candidates = new ArrayList<>();
walk(
cursor,
candidates,
node ->
isDeclarationWithName(node, name)
&& node.getParentNode().isPresent()
&& !node.getParentNode().get().equals(cursor));
cursor,
candidates,
node ->
isDeclarationWithName(node, name)
&& node.getParentNode().isPresent()
&& !node.getParentNode().get().equals(cursor));
if (index >= candidates.size()) {
throw new TargetClassNotFound("Non-Direct-Inner-Class", index + name, cursor);
}
Expand Down Expand Up @@ -369,7 +369,7 @@ private static boolean isDeclarationWithName(Node node, String name) {
* @throws TargetClassNotFound if the target class is not found.
*/
private static Node findAnonymousClassOrEnumConstant(Node cursor, int index)
throws TargetClassNotFound {
throws TargetClassNotFound {
final List<Node> candidates = new ArrayList<>();
if (cursor instanceof EnumDeclaration) {
// According to the Java language specification, enum constants are the first members of
Expand All @@ -383,14 +383,14 @@ private static Node findAnonymousClassOrEnumConstant(Node cursor, int index)
index -= constants.size();
}
walk(
cursor,
candidates,
node -> {
if (node instanceof ObjectCreationExpr) {
return ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent();
}
return false;
});
cursor,
candidates,
node -> {
if (node instanceof ObjectCreationExpr) {
return ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent();
}
return false;
});
if (index >= candidates.size()) {
throw new TargetClassNotFound("Top-Level-Anonymous-Class", "$" + index, cursor);
}
Expand Down Expand Up @@ -459,15 +459,15 @@ private static String extractIntegerFromBeginningOfStringInString(String key) {
*/
private static void walk(Node cursor, List<Node> candidates, Predicate<Node> predicate) {
cursor.walk(
Node.TreeTraversal.DIRECT_CHILDREN,
node -> {
if (!isTypeDeclarationOrAnonymousClass(node)) {
walk(node, candidates, predicate);
}
if (predicate.test(node)) {
candidates.add(node);
}
});
Node.TreeTraversal.DIRECT_CHILDREN,
node -> {
if (!isTypeDeclarationOrAnonymousClass(node)) {
walk(node, candidates, predicate);
}
if (predicate.test(node)) {
candidates.add(node);
}
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public void additionOnFullyQualifiedTypeNamesTest() {
"import edu.ucr.custom.Nullable;",
"public class Foo {",
" java.lang.@Nullable Object bar;",
" java.util.@Nullable Map<java.lang.@Nullable String, @Nullable String[]> f0;",
" java.util.@Nullable Map<java.lang.@Nullable String, String@Nullable []> f0;",
" java.lang.@Nullable Object baz(java.lang.@Nullable Object param) {;",
" java.lang.@Nullable Object localVar;",
" return new Object();",
Expand Down Expand Up @@ -175,7 +175,7 @@ public void deletionOnFullyQualifiedTypeNamesTest() {
"import edu.ucr.custom.Nullable;",
"public class Foo {",
" java.lang.@Nullable Object bar;",
" java.util.@Nullable Map<java.lang.@Nullable String, @Nullable String[]> f0;",
" java.util.@Nullable Map<java.lang.@Nullable String, String @Nullable []> f0;",
" java.lang.@Nullable Object baz(java.lang.@Nullable Object param) {;",
" java.lang.@Nullable Object localVar;",
" return new Object();",
Expand All @@ -186,7 +186,7 @@ public void deletionOnFullyQualifiedTypeNamesTest() {
"import edu.ucr.custom.Nullable;",
"public class Foo {",
" java.lang.Object bar;",
" java.util.Map<java.lang.String, String[]> f0;",
" java.util.Map<java.lang.String, String []> f0;",
" java.lang.Object baz(java.lang.Object param) {;",
" java.lang.Object localVar;",
" return new Object();",
Expand Down Expand Up @@ -222,17 +222,17 @@ public void additionOnArrayTest() {
" public void foo() {",
" java.util.Map<java.lang.String, String[]> f0;",
" Map<T, T>[] f1;",
" String[] f2;",
" int[] f2;",
" }",
"}")
.expectOutput(
"package test;",
"import edu.ucr.custom.Nullable;",
"public class Foo<T> {",
" public void foo() {",
" java.util.@Nullable Map<java.lang.@Nullable String, @Nullable String[]> f0;",
" @Nullable Map<@Nullable T, @Nullable T>[] f1;",
" @Nullable String[] f2;",
" java.util.@Nullable Map<java.lang.@Nullable String, String@Nullable []> f0;",
" Map<@Nullable T, @Nullable T>@Nullable [] f1;",
" int@Nullable [] f2;",
" }",
"}")
.addChanges(
Expand All @@ -245,7 +245,7 @@ public void additionOnArrayTest() {
new OnLocalVariable("Foo.java", "test.Foo", "foo()", "f1"),
"edu.ucr.custom.Nullable",
ImmutableList.of(
ImmutableList.of(0), ImmutableList.of(1, 0), ImmutableList.of(2, 0))),
ImmutableList.of(0), ImmutableList.of(1, 1, 0), ImmutableList.of(1, 2, 0))),
new AddTypeUseMarkerAnnotation(
new OnLocalVariable("Foo.java", "test.Foo", "foo()", "f2"),
"edu.ucr.custom.Nullable"))
Expand All @@ -261,14 +261,14 @@ public void deletionOnArrayTest() {
"import edu.ucr.custom.Nullable;",
"public class Foo {",
" java.util.Map<String, String[]> f0;",
" java.util.@Nullable Map<@Nullable String, @Nullable String[]> f1;",
" @Nullable Map<java.util.@Nullable Map, @Nullable String>[] f2;",
" java.util.@Nullable Map<@Nullable String, String@Nullable []> f1;",
" Map<java.util.@Nullable Map, @Nullable String>@Nullable [] f2;",
"}")
.expectOutput(
"package test;",
"import edu.ucr.custom.Nullable;",
"public class Foo {",
" java.util.@Nullable Map<@Nullable String, @Nullable String[]> f0;",
" java.util.@Nullable Map<@Nullable String, String@Nullable []> f0;",
" java.util.Map<String, String[]> f1;",
" Map<java.util.Map, String>[] f2;",
"}")
Expand All @@ -287,7 +287,7 @@ public void deletionOnArrayTest() {
new OnField("Foo.java", "test.Foo", Set.of("f2")),
"edu.ucr.custom.Nullable",
ImmutableList.of(
ImmutableList.of(0), ImmutableList.of(1, 0), ImmutableList.of(2, 0))))
ImmutableList.of(0), ImmutableList.of(1, 1, 0), ImmutableList.of(1, 2, 0))))
.start();
}

Expand Down Expand Up @@ -409,7 +409,7 @@ public void deletionOnInitializerTest() {
" @Nullable int f0 = 0;",
" @Nullable Bar<@Nullable String, @Nullable Integer, @Nullable Baz<@Nullable String, @Nullable Integer>> f1 = new Bar<@Nullable String, @Nullable Integer, @Nullable Baz<@Nullable String, @Nullable Integer>>();",
" @Nullable String f2 = \"FOO\";",
" @Nullable Bar<@Nullable String, @Nullable Integer[], @Nullable Baz<@Nullable String, @Nullable Integer>> f3 = new Bar<@Nullable String, @Nullable Integer[], @Nullable Baz<@Nullable String, @Nullable Integer>>();",
" @Nullable Bar<@Nullable String, Integer@Nullable [], @Nullable Baz<@Nullable String, @Nullable Integer>> f3 = new Bar<@Nullable String, Integer@Nullable [], @Nullable Baz<@Nullable String, @Nullable Integer>>();",
" }",
"}")
.expectOutput(
Expand Down Expand Up @@ -775,4 +775,50 @@ public void multipleInlineLocalVariableTest() {
ImmutableList.of(ImmutableList.of(1, 0))))
.start();
}

@Test
public void nullableArrayAdditionOnReference() {
injectorTestHelper
.addInput(
"Foo.java",
"package test;",
"import javax.annotation.Nullable;",
"public class Foo {",
" Object[] h = new Object[4];",
"}")
.expectOutput(
"package test;",
"import javax.annotation.Nullable;",
"public class Foo {",
" Object@Nullable [] h = new Object[4];",
"}")
.addChanges(
new AddTypeUseMarkerAnnotation(
new OnField("Foo.java", "test.Foo", Collections.singleton("h")),
"javax.annotation.Nullable"))
.start();
}

@Test
public void nullableArrayDeletionOnReference() {
injectorTestHelper
.addInput(
"Foo.java",
"package test;",
"import javax.annotation.Nullable;",
"public class Foo {",
" Object@Nullable [] h = new Object[4];",
"}")
.expectOutput(
"package test;",
"import javax.annotation.Nullable;",
"public class Foo {",
" Object[] h = new Object[4];",
"}")
.addChanges(
new RemoveTypeUseMarkerAnnotation(
new OnField("Foo.java", "test.Foo", Collections.singleton("h")),
"javax.annotation.Nullable"))
.start();
}
}

0 comments on commit 8924cdc

Please sign in to comment.