From ae85f9bf86252952ee8cb89d5c29cb4f1b524f05 Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Tue, 4 Apr 2023 10:57:27 -0700 Subject: [PATCH 01/10] add visitor architecture --- .../cs/riple/injector/location/Location.java | 11 +++ .../injector/location/LocationVisitor.java | 69 +++++++++++++++++++ .../cs/riple/injector/location/OnClass.java | 5 ++ .../cs/riple/injector/location/OnField.java | 5 ++ .../cs/riple/injector/location/OnMethod.java | 5 ++ .../riple/injector/location/OnParameter.java | 5 ++ 6 files changed, 100 insertions(+) create mode 100644 injector/src/main/java/edu/ucr/cs/riple/injector/location/LocationVisitor.java diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java index d449cfd7c..50dcaeac9 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java @@ -268,6 +268,17 @@ public boolean equals(Object o) { return type == other.type && clazz.equals(other.clazz); } + /** + * Applies a visitor to this location. + * + * @param the return type of the visitor's methods + * @param

the type of the additional parameter to the visitor's methods + * @param v the visitor operating on this type + * @param p additional parameter to the visitor + * @return a visitor-specified result + */ + abstract R accept(LocationVisitor v, P p); + @Override public int hashCode() { return Objects.hash(type, clazz); diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/LocationVisitor.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/LocationVisitor.java new file mode 100644 index 000000000..83f82332d --- /dev/null +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/LocationVisitor.java @@ -0,0 +1,69 @@ +/* + * MIT License + * + * Copyright (c) 2023 Nima Karimipour + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package edu.ucr.cs.riple.injector.location; + +/** + * A visitor of types, in the style of the visitor design pattern. When a visitor is passed to a + * location's {@link Location#accept accept} method, the visitXyz method + * applicable to that location is invoked. + */ +public interface LocationVisitor { + + /** + * Visits a location for a method. + * + * @param onMethod the location for a method + * @param p a visitor-specified parameter + * @return a visitor-specified result + */ + R visitMethod(OnMethod onMethod, P p); + + /** + * Visits a location for a field. + * + * @param onField the location for a field + * @param p a visitor-specified parameter + * @return a visitor-specified result + */ + R visitField(OnField onField, P p); + + /** + * Visits a location for a parameter. + * + * @param onParameter the location for a parameter + * @param p a visitor-specified parameter + * @return a visitor-specified result + */ + R visitParameter(OnParameter onParameter, P p); + + /** + * Visits a location for a class. + * + * @param onClass the location for a class + * @param p a visitor-specified parameter + * @return a visitor-specified result + */ + R visitClass(OnClass onClass, P p); +} diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java index b9270eb39..1ac715c93 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java @@ -81,6 +81,11 @@ protected void fillJsonInformation(JSONObject res) { // no op } + @Override + R accept(LocationVisitor v, P p) { + return v.visitClass(this, p); + } + @Override public String toString() { return "OnClass{" + "type=" + type + ", clazz='" + clazz + '\'' + ", path=" + path + '}'; diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java index 6381e2a9c..0261f6ab2 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java @@ -129,6 +129,11 @@ public boolean equals(Object o) { return super.equals(other) && !Collections.disjoint(variables, other.variables); } + @Override + R accept(LocationVisitor v, P p) { + return v.visitField(this, p); + } + @Override public int hashCode() { return Objects.hash(super.hashCode(), variables); diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java index 499322998..85b03a78a 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java @@ -117,6 +117,11 @@ public boolean equals(Object o) { return super.equals(other) && method.equals(other.method); } + @Override + R accept(LocationVisitor v, P p) { + return v.visitMethod(this, p); + } + @Override public int hashCode() { return Objects.hash(super.hashCode(), method); diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java index db5763a30..7279c6b0f 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java @@ -125,6 +125,11 @@ public boolean equals(Object o) { return super.equals(other) && method.equals(other.method) && index == other.index; } + @Override + R accept(LocationVisitor v, P p) { + return v.visitParameter(this, p); + } + @Override public int hashCode() { return Objects.hash(super.hashCode(), method, index); From ed7bda6541f69b02f78cb1a32aca241764d37e76 Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Tue, 4 Apr 2023 11:50:56 -0700 Subject: [PATCH 02/10] update visitibility to public --- .../main/java/edu/ucr/cs/riple/injector/location/Location.java | 2 +- .../main/java/edu/ucr/cs/riple/injector/location/OnClass.java | 2 +- .../main/java/edu/ucr/cs/riple/injector/location/OnField.java | 2 +- .../main/java/edu/ucr/cs/riple/injector/location/OnMethod.java | 2 +- .../java/edu/ucr/cs/riple/injector/location/OnParameter.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java index 50dcaeac9..f19fd9ed7 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java @@ -277,7 +277,7 @@ public boolean equals(Object o) { * @param p additional parameter to the visitor * @return a visitor-specified result */ - abstract R accept(LocationVisitor v, P p); + public abstract R accept(LocationVisitor v, P p); @Override public int hashCode() { diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java index 1ac715c93..86af0b459 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java @@ -82,7 +82,7 @@ protected void fillJsonInformation(JSONObject res) { } @Override - R accept(LocationVisitor v, P p) { + public R accept(LocationVisitor v, P p) { return v.visitClass(this, p); } diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java index 0261f6ab2..e4de051a0 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java @@ -130,7 +130,7 @@ public boolean equals(Object o) { } @Override - R accept(LocationVisitor v, P p) { + public R accept(LocationVisitor v, P p) { return v.visitField(this, p); } diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java index 85b03a78a..c57287d4b 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java @@ -118,7 +118,7 @@ public boolean equals(Object o) { } @Override - R accept(LocationVisitor v, P p) { + public R accept(LocationVisitor v, P p) { return v.visitMethod(this, p); } diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java index 7279c6b0f..b1aaad7c1 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java @@ -126,7 +126,7 @@ public boolean equals(Object o) { } @Override - R accept(LocationVisitor v, P p) { + public R accept(LocationVisitor v, P p) { return v.visitParameter(this, p); } From 2a5b987b805db27f9414966be58876c55c37a6c3 Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Tue, 4 Apr 2023 11:52:01 -0700 Subject: [PATCH 03/10] initial commit --- .../riple/injector/changes/ChangeVisitor.java | 84 +++++++++++++++++++ .../cs/riple/injector/location/Location.java | 2 +- .../cs/riple/injector/location/OnField.java | 2 +- 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java new file mode 100644 index 000000000..103eee068 --- /dev/null +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2023 University of California, Riverside. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package edu.ucr.cs.riple.injector.changes; + +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.NodeList; +import com.github.javaparser.ast.body.BodyDeclaration; +import com.github.javaparser.utils.Pair; +import edu.ucr.cs.riple.injector.Helper; +import edu.ucr.cs.riple.injector.exceptions.TargetClassNotFound; +import edu.ucr.cs.riple.injector.location.LocationVisitor; +import edu.ucr.cs.riple.injector.location.OnClass; +import edu.ucr.cs.riple.injector.location.OnField; +import edu.ucr.cs.riple.injector.location.OnMethod; +import edu.ucr.cs.riple.injector.location.OnParameter; +import edu.ucr.cs.riple.injector.modifications.Modification; + +public class ChangeVisitor + implements LocationVisitor>, Change>> { + + private final CompilationUnit cu; + + public ChangeVisitor(CompilationUnit cu) { + this.cu = cu; + } + + @Override + public Modification visitMethod( + OnMethod onMethod, Pair>, Change> nodeListChangePair) { + return null; + } + + @Override + public Modification visitField( + OnField onField, Pair>, Change> nodeListChangePair) { + return null; + } + + @Override + public Modification visitParameter( + OnParameter onParameter, Pair>, Change> nodeListChangePair) { + return null; + } + + @Override + public Modification visitClass( + OnClass onClass, Pair>, Change> nodeListChangePair) { + return null; + } + + public Modification visit(Change change) { + NodeList> members; + try { + members = Helper.getTypeDeclarationMembersByFlatName(cu, change.location.clazz); + if (members == null) { + return null; + } + return change.location.accept(this, new Pair<>(members, change)); + } catch (TargetClassNotFound notFound) { + System.err.println(notFound.getMessage()); + return null; + } + } +} diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java index 50dcaeac9..f19fd9ed7 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java @@ -277,7 +277,7 @@ public boolean equals(Object o) { * @param p additional parameter to the visitor * @return a visitor-specified result */ - abstract R accept(LocationVisitor v, P p); + public abstract R accept(LocationVisitor v, P p); @Override public int hashCode() { diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java index 0261f6ab2..e4de051a0 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java @@ -130,7 +130,7 @@ public boolean equals(Object o) { } @Override - R accept(LocationVisitor v, P p) { + public R accept(LocationVisitor v, P p) { return v.visitField(this, p); } From ee5e7a4a526102cd65c8c3bdad015035efb2b0ef Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Tue, 4 Apr 2023 12:30:56 -0700 Subject: [PATCH 04/10] use visitor for applying changes on the locations --- .../ucr/cs/riple/injector/changes/Change.java | 2 +- .../riple/injector/changes/ChangeVisitor.java | 119 ++++++++++++++++-- .../cs/riple/injector/location/Location.java | 36 ------ .../cs/riple/injector/location/OnClass.java | 21 ---- .../cs/riple/injector/location/OnField.java | 31 ----- .../cs/riple/injector/location/OnMethod.java | 38 +----- .../riple/injector/location/OnParameter.java | 40 +----- 7 files changed, 118 insertions(+), 169 deletions(-) diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java index b834625db..ce16f90e1 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java @@ -56,7 +56,7 @@ public Change(Location location, String annotation) { */ @Nullable public Modification translate(CompilationUnit tree) { - return this.location.apply(tree, this); + return new ChangeVisitor(tree).visit(this); } /** diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java index 103eee068..06172fcce 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java @@ -22,9 +22,14 @@ package edu.ucr.cs.riple.injector.changes; +import static edu.ucr.cs.riple.injector.location.OnClass.isAnonymousClassFlatName; + import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.BodyDeclaration; +import com.github.javaparser.ast.body.Parameter; +import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.utils.Pair; import edu.ucr.cs.riple.injector.Helper; import edu.ucr.cs.riple.injector.exceptions.TargetClassNotFound; @@ -34,10 +39,15 @@ import edu.ucr.cs.riple.injector.location.OnMethod; import edu.ucr.cs.riple.injector.location.OnParameter; import edu.ucr.cs.riple.injector.modifications.Modification; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Nullable; +/** A visitor for applying changes to a compilation unit on a specified location. */ public class ChangeVisitor implements LocationVisitor>, Change>> { + /** Compilation unit which the changes will be applied. */ private final CompilationUnit cu; public ChangeVisitor(CompilationUnit cu) { @@ -45,29 +55,118 @@ public ChangeVisitor(CompilationUnit cu) { } @Override + @Nullable public Modification visitMethod( - OnMethod onMethod, Pair>, Change> nodeListChangePair) { - return null; + OnMethod onMethod, Pair>, Change> pair) { + final AtomicReference ans = new AtomicReference<>(); + final NodeList> members = pair.a; + final Change change = pair.b; + members.forEach( + bodyDeclaration -> + bodyDeclaration.ifCallableDeclaration( + callableDeclaration -> { + if (ans.get() != null) { + // already found the member. + return; + } + if (onMethod.matchesCallableDeclaration(callableDeclaration)) { + ans.set(change.visit(callableDeclaration)); + } + })); + if (ans.get() == null) { + members.forEach( + bodyDeclaration -> + bodyDeclaration.ifAnnotationMemberDeclaration( + annotationMemberDeclaration -> { + if (annotationMemberDeclaration + .getNameAsString() + .equals(Helper.extractCallableName(onMethod.method))) { + ans.set(change.visit(annotationMemberDeclaration)); + } + })); + } + return ans.get(); } @Override - public Modification visitField( - OnField onField, Pair>, Change> nodeListChangePair) { - return null; + @Nullable + public Modification visitField(OnField onField, Pair>, Change> pair) { + final AtomicReference ans = new AtomicReference<>(); + final NodeList> members = pair.a; + final Change change = pair.b; + members.forEach( + bodyDeclaration -> + bodyDeclaration.ifFieldDeclaration( + fieldDeclaration -> { + if (ans.get() != null) { + // already found the member. + return; + } + NodeList vars = + fieldDeclaration.asFieldDeclaration().getVariables(); + for (VariableDeclarator v : vars) { + if (onField.variables.contains(v.getName().toString())) { + ans.set(change.visit(fieldDeclaration)); + break; + } + } + })); + return ans.get(); } @Override + @Nullable public Modification visitParameter( - OnParameter onParameter, Pair>, Change> nodeListChangePair) { - return null; + OnParameter onParameter, Pair>, Change> pair) { + final AtomicReference ans = new AtomicReference<>(); + final NodeList> members = pair.a; + final Change change = pair.b; + members.forEach( + bodyDeclaration -> + bodyDeclaration.ifCallableDeclaration( + callableDeclaration -> { + if (ans.get() != null) { + // already found the member. + return; + } + if (onParameter.matchesCallableDeclaration(callableDeclaration)) { + NodeList params = callableDeclaration.getParameters(); + if (onParameter.index < params.size()) { + if (params.get(onParameter.index) != null) { + Node param = params.get(onParameter.index); + if (param instanceof Parameter) { + ans.set(change.visit((Parameter) param)); + } + } + } + } + })); + return ans.get(); } @Override - public Modification visitClass( - OnClass onClass, Pair>, Change> nodeListChangePair) { - return null; + @Nullable + public Modification visitClass(OnClass onClass, Pair>, Change> pair) { + final NodeList> members = pair.a; + final Change change = pair.b; + if (isAnonymousClassFlatName(change.location.clazz)) { + return null; + } + // Get the enclosing class of the members + Optional optionalClass = members.getParentNode(); + if (optionalClass.isEmpty() || !(optionalClass.get() instanceof BodyDeclaration)) { + return null; + } + return change.visit(((BodyDeclaration) optionalClass.get())); } + /** + * Applies the change to the compilation unit. + * + * @param change the change to apply. + * @return the modification that should be applied. + */ + @Nullable public Modification visit(Change change) { NodeList> members; try { diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java index f19fd9ed7..022921680 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java @@ -24,15 +24,9 @@ package edu.ucr.cs.riple.injector.location; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.body.BodyDeclaration; import com.google.common.base.Preconditions; import com.google.common.collect.Sets; import edu.ucr.cs.riple.injector.Helper; -import edu.ucr.cs.riple.injector.changes.Change; -import edu.ucr.cs.riple.injector.exceptions.TargetClassNotFound; -import edu.ucr.cs.riple.injector.modifications.Modification; import java.nio.file.Path; import java.util.Arrays; import java.util.Objects; @@ -115,17 +109,6 @@ public static Location createLocationFromArrayInfo(String[] values) { throw new RuntimeException("Cannot reach this statement, values: " + Arrays.toString(values)); } - /** - * Applies the change to the element in this location. - * - * @param members The list of members of the enclosing class of the target element. - * @param change The change to be applied on the target element. - * @return The modification that should be applied on the source file. - */ - @Nullable - protected abstract Modification applyToMember( - NodeList> members, Change change); - /** * Fills the given JSON object with the information of this location. * @@ -133,25 +116,6 @@ protected abstract Modification applyToMember( */ protected abstract void fillJsonInformation(JSONObject res); - /** - * Applies the change to the target element on the given compilation unit tree. - * - * @param tree CompilationUnit Tree to locate the target element. - * @param change Change to be applied on the target element. - * @return The modification that should be applied on the source file. - */ - @Nullable - public Modification apply(CompilationUnit tree, Change change) { - NodeList> clazz; - try { - clazz = Helper.getTypeDeclarationMembersByFlatName(tree, this.clazz); - } catch (TargetClassNotFound notFound) { - System.err.println(notFound.getMessage()); - return null; - } - return applyToMember(clazz, change); - } - @SuppressWarnings("unchecked") public JSONObject getJson() { JSONObject res = new JSONObject(); diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java index 86af0b459..2a185cba6 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java @@ -24,16 +24,9 @@ package edu.ucr.cs.riple.injector.location; -import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.body.BodyDeclaration; import edu.ucr.cs.riple.injector.Helper; -import edu.ucr.cs.riple.injector.changes.Change; -import edu.ucr.cs.riple.injector.modifications.Modification; import java.nio.file.Path; -import java.util.Optional; import java.util.regex.Pattern; -import javax.annotation.Nullable; import org.json.simple.JSONObject; /** Represents a location for class element. This location is used to apply changes to a class. */ @@ -53,20 +46,6 @@ public OnClass(String path, String clazz) { this(Helper.deserializePath(path), clazz); } - @Override - @Nullable - protected Modification applyToMember(NodeList> members, Change change) { - if (isAnonymousClassFlatName(change.location.clazz)) { - return null; - } - // Get the enclosing class of the members - Optional optionalClass = members.getParentNode(); - if (optionalClass.isEmpty() || !(optionalClass.get() instanceof BodyDeclaration)) { - return null; - } - return change.visit(((BodyDeclaration) optionalClass.get())); - } - /** * Checks if flat name is for an anonymous class. * diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java index e4de051a0..34305190c 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java @@ -24,19 +24,12 @@ package edu.ucr.cs.riple.injector.location; -import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.body.BodyDeclaration; -import com.github.javaparser.ast.body.VariableDeclarator; import edu.ucr.cs.riple.injector.Helper; -import edu.ucr.cs.riple.injector.changes.Change; -import edu.ucr.cs.riple.injector.modifications.Modification; import java.nio.file.Path; import java.util.Collections; import java.util.Objects; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -import javax.annotation.Nullable; import org.json.simple.JSONArray; import org.json.simple.JSONObject; @@ -76,30 +69,6 @@ protected void fillJsonInformation(JSONObject res) { res.put(KEYS.VARIABLES, fields); } - @Override - @Nullable - protected Modification applyToMember(NodeList> members, Change change) { - final AtomicReference ans = new AtomicReference<>(); - members.forEach( - bodyDeclaration -> - bodyDeclaration.ifFieldDeclaration( - fieldDeclaration -> { - if (ans.get() != null) { - // already found the member. - return; - } - NodeList vars = - fieldDeclaration.asFieldDeclaration().getVariables(); - for (VariableDeclarator v : vars) { - if (variables.contains(v.getName().toString())) { - ans.set(change.visit(fieldDeclaration)); - break; - } - } - })); - return ans.get(); - } - @Override public void ifField(Consumer consumer) { consumer.accept(this); diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java index c57287d4b..db3414472 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java @@ -24,17 +24,12 @@ package edu.ucr.cs.riple.injector.location; -import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.body.BodyDeclaration; +import com.github.javaparser.ast.body.CallableDeclaration; import edu.ucr.cs.riple.injector.Helper; import edu.ucr.cs.riple.injector.SignatureMatcher; -import edu.ucr.cs.riple.injector.changes.Change; -import edu.ucr.cs.riple.injector.modifications.Modification; import java.nio.file.Path; import java.util.Objects; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -import javax.annotation.Nullable; import org.json.simple.JSONObject; /** Represents a location for method element. This location is used to apply changes to a method. */ @@ -64,35 +59,8 @@ protected void fillJsonInformation(JSONObject res) { res.put(KEYS.METHOD, method); } - @Override - @Nullable - protected Modification applyToMember(NodeList> members, Change change) { - final AtomicReference ans = new AtomicReference<>(); - members.forEach( - bodyDeclaration -> - bodyDeclaration.ifCallableDeclaration( - callableDeclaration -> { - if (ans.get() != null) { - // already found the member. - return; - } - if (this.matcher.matchesCallableDeclaration(callableDeclaration)) { - ans.set(change.visit(callableDeclaration)); - } - })); - if (ans.get() == null) { - members.forEach( - bodyDeclaration -> - bodyDeclaration.ifAnnotationMemberDeclaration( - annotationMemberDeclaration -> { - if (annotationMemberDeclaration - .getNameAsString() - .equals(Helper.extractCallableName(method))) { - ans.set(change.visit(annotationMemberDeclaration)); - } - })); - } - return ans.get(); + public boolean matchesCallableDeclaration(CallableDeclaration method) { + return this.matcher.matchesCallableDeclaration(method); } @Override diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java index b1aaad7c1..dee0442aa 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java @@ -24,19 +24,12 @@ package edu.ucr.cs.riple.injector.location; -import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.body.BodyDeclaration; -import com.github.javaparser.ast.body.Parameter; +import com.github.javaparser.ast.body.CallableDeclaration; import edu.ucr.cs.riple.injector.Helper; import edu.ucr.cs.riple.injector.SignatureMatcher; -import edu.ucr.cs.riple.injector.changes.Change; -import edu.ucr.cs.riple.injector.modifications.Modification; import java.nio.file.Path; import java.util.Objects; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -import javax.annotation.Nullable; import org.json.simple.JSONObject; /** @@ -73,33 +66,6 @@ protected void fillJsonInformation(JSONObject res) { res.put(KEYS.INDEX, index); } - @Override - @Nullable - protected Modification applyToMember(NodeList> members, Change change) { - final AtomicReference ans = new AtomicReference<>(); - members.forEach( - bodyDeclaration -> - bodyDeclaration.ifCallableDeclaration( - callableDeclaration -> { - if (ans.get() != null) { - // already found the member. - return; - } - if (matcher.matchesCallableDeclaration(callableDeclaration)) { - NodeList params = callableDeclaration.getParameters(); - if (index < params.size()) { - if (params.get(index) != null) { - Node param = params.get(index); - if (param instanceof Parameter) { - ans.set(change.visit((Parameter) param)); - } - } - } - } - })); - return ans.get(); - } - @Override public void ifParameter(Consumer consumer) { consumer.accept(this); @@ -125,6 +91,10 @@ public boolean equals(Object o) { return super.equals(other) && method.equals(other.method) && index == other.index; } + public boolean matchesCallableDeclaration(CallableDeclaration method) { + return this.matcher.matchesCallableDeclaration(method); + } + @Override public R accept(LocationVisitor v, P p) { return v.visitParameter(this, p); From e30d077ce659dd3bb72bacc31407020e29628800 Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Tue, 4 Apr 2023 16:20:05 -0700 Subject: [PATCH 05/10] add javadoc --- .../java/edu/ucr/cs/riple/injector/location/OnMethod.java | 6 ++++++ .../edu/ucr/cs/riple/injector/location/OnParameter.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java index db3414472..6f656c232 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java @@ -59,6 +59,12 @@ protected void fillJsonInformation(JSONObject res) { res.put(KEYS.METHOD, method); } + /** + * Checks if the given method matches the method signature of this location. + * + * @param method method to check. + * @return true, if the given method matches the method signature of this location. + */ public boolean matchesCallableDeclaration(CallableDeclaration method) { return this.matcher.matchesCallableDeclaration(method); } diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java index dee0442aa..f63188433 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java @@ -91,6 +91,12 @@ public boolean equals(Object o) { return super.equals(other) && method.equals(other.method) && index == other.index; } + /** + * Checks if the given method matches the method signature of this location. + * + * @param method method to check. + * @return true if the method matches the method signature of this location. + */ public boolean matchesCallableDeclaration(CallableDeclaration method) { return this.matcher.matchesCallableDeclaration(method); } From a018ff3be2b5919f5a414af0e952d0727b4431b2 Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Tue, 4 Apr 2023 20:03:44 -0700 Subject: [PATCH 06/10] remvoe translate method --- .../java/edu/ucr/cs/riple/injector/Injector.java | 4 +++- .../edu/ucr/cs/riple/injector/changes/Change.java | 13 ------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/Injector.java b/injector/src/main/java/edu/ucr/cs/riple/injector/Injector.java index bd6be6a17..27618e135 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/Injector.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/Injector.java @@ -29,6 +29,7 @@ import com.github.javaparser.ast.ImportDeclaration; import edu.ucr.cs.riple.injector.changes.AddAnnotation; import edu.ucr.cs.riple.injector.changes.Change; +import edu.ucr.cs.riple.injector.changes.ChangeVisitor; import edu.ucr.cs.riple.injector.changes.RemoveAnnotation; import edu.ucr.cs.riple.injector.modifications.Modification; import edu.ucr.cs.riple.injector.offsets.FileOffsetStore; @@ -62,11 +63,12 @@ public Set start(Set changes) { } catch (IOException exception) { return; } + ChangeVisitor visitor = new ChangeVisitor(tree); Set modifications = new HashSet<>(); Set imports = new HashSet<>(); for (Change change : changeList) { try { - Modification modification = change.translate(tree); + Modification modification = visitor.visit(change); if (modification != null) { modifications.add(modification); if (change instanceof AddAnnotation) { diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java index ce16f90e1..482f68d13 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java @@ -22,7 +22,6 @@ package edu.ucr.cs.riple.injector.changes; -import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations; import com.github.javaparser.ast.nodeTypes.NodeWithRange; import edu.ucr.cs.riple.injector.Helper; @@ -47,18 +46,6 @@ public Change(Location location, String annotation) { this.annotationSimpleName = Helper.simpleName(annotation); } - /** - * Translate the change to a text modification in the source file. - * - * @param tree Compilation unit tree instance. - * @return A text modification instance if the translation is successful, otherwise {@code null} - * will be returned. - */ - @Nullable - public Modification translate(CompilationUnit tree) { - return new ChangeVisitor(tree).visit(this); - } - /** * Visits the given node and translates the change to a text modification. * From 15ff010019a8ee78522ed2f7905546c62f94be8d Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Wed, 19 Apr 2023 13:15:57 -0700 Subject: [PATCH 07/10] rename visit to computeModification --- injector/src/main/java/edu/ucr/cs/riple/injector/Injector.java | 2 +- .../java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/Injector.java b/injector/src/main/java/edu/ucr/cs/riple/injector/Injector.java index 27618e135..331fde812 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/Injector.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/Injector.java @@ -68,7 +68,7 @@ public Set start(Set changes) { Set imports = new HashSet<>(); for (Change change : changeList) { try { - Modification modification = visitor.visit(change); + Modification modification = visitor.computeModification(change); if (modification != null) { modifications.add(modification); if (change instanceof AddAnnotation) { diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java index 06172fcce..6bffb5df1 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java @@ -167,7 +167,7 @@ public Modification visitClass(OnClass onClass, Pair * @return the modification that should be applied. */ @Nullable - public Modification visit(Change change) { + public Modification computeModification(Change change) { NodeList> members; try { members = Helper.getTypeDeclarationMembersByFlatName(cu, change.location.clazz); From 2e2dd6b83be323d4f97964abe8749cb242564aa8 Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Wed, 19 Apr 2023 13:18:22 -0700 Subject: [PATCH 08/10] reword javadoc for ChangeVisitor --- .../edu/ucr/cs/riple/injector/changes/ChangeVisitor.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java index 6bffb5df1..8bc64ddec 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java @@ -43,7 +43,10 @@ import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nullable; -/** A visitor for applying changes to a compilation unit on a specified location. */ +/** + * A visitor for computing the required {@link Modification} to a compilation unit on a specified + * location for the requested change. + */ public class ChangeVisitor implements LocationVisitor>, Change>> { From a2dcdd99c84f60f1293e3daa5fc3cba86defa880 Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Wed, 19 Apr 2023 13:20:05 -0700 Subject: [PATCH 09/10] merged master into this --- .../java/edu/ucr/cs/riple/injector/location/OnParameter.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java index 16c896a59..f63188433 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java @@ -106,11 +106,6 @@ public R accept(LocationVisitor v, P p) { return v.visitParameter(this, p); } - @Override - public R accept(LocationVisitor v, P p) { - return v.visitParameter(this, p); - } - @Override public int hashCode() { return Objects.hash(super.hashCode(), method, index); From 66edb7ea867ee787ae68f7ebe2a367b2e3bc8e5c Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Wed, 19 Apr 2023 14:49:59 -0700 Subject: [PATCH 10/10] update javadoc --- .../java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java index 8bc64ddec..0115287f8 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/ChangeVisitor.java @@ -164,7 +164,8 @@ public Modification visitClass(OnClass onClass, Pair } /** - * Applies the change to the compilation unit. + * Computes the required {@link Modification} that should be applied to the compilation unit for + * the given change. * * @param change the change to apply. * @return the modification that should be applied.