Skip to content

Commit

Permalink
more pipeline updates
Browse files Browse the repository at this point in the history
some tweaks to field()/value() unwrapping (wip)
  • Loading branch information
evanchooly committed Jan 28, 2025
1 parent 0fdfe28 commit 9fde65a
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,22 @@ public static Expression isNumber(Object input) {
* @aggregation.expression $toBool
*/
public static Expression toBool(Object input) {

return new Expression("$toBool", wrap(input));
}

/**
* Converts value to a Date.
*
* @param input the value to process
* @return the new expression
* @aggregation.expression $toDate
* @see DateExpressions#toDate(Object)
*/
public static Expression toDate(Object input) {
return DateExpressions.toDate(input);
}

/**
* Converts value to a Decimal128.
*
Expand Down
2 changes: 1 addition & 1 deletion rewrite/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-recipe-bom</artifactId>
<version>3.0.1</version>
<version>3.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import java.util.ArrayList;
import java.util.List;

import dev.morphia.aggregation.stages.Limit;
import dev.morphia.aggregation.stages.Match;
import dev.morphia.aggregation.stages.Skip;
import dev.morphia.aggregation.stages.SortByCount;
import dev.morphia.aggregation.stages.Stage;
import dev.morphia.query.filters.Filter;

import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -53,10 +57,12 @@ public class PipelineRewrite extends Recipe {
new MethodMatcher(AGGREGATION + " replaceRoot(dev.morphia.aggregation.stages.ReplaceRoot)"),
new MethodMatcher(AGGREGATION + " replaceWith(dev.morphia.aggregation.stages.ReplaceWith)"),
new MethodMatcher(AGGREGATION + " sample(dev.morphia.aggregation.stages.Sample)"),
new MethodMatcher(AGGREGATION + " set(dev.morphia.aggregation.stages.AddFields)"),
new MethodMatcher(AGGREGATION + " set(dev.morphia.aggregation.stages.Set)"),
new MethodMatcher(AGGREGATION + " skip(long)"),
new MethodMatcher(AGGREGATION + " sort(dev.morphia.aggregation.stages.Sort)"),
new MethodMatcher(AGGREGATION + " sortByCount(dev.morphia.aggregation.stages.SortByCount)"),
new MethodMatcher(AGGREGATION + " sortByCount(dev.morphia.aggregation.expressions.impls.Expression)"),
new MethodMatcher(AGGREGATION + " unionWith(Class,Stage...)"),
new MethodMatcher(AGGREGATION + " unionWith(String,Stage...)"),
new MethodMatcher(AGGREGATION + " unset(dev.morphia.aggregation.stages.Unset)"),
Expand All @@ -70,12 +76,27 @@ public boolean matches(@Nullable MethodCall methodCall) {
}
};

private static final JavaTemplate LIMIT = (JavaTemplate.builder("Limit.limit()"))
.javaParser(JavaParser.fromJavaVersion()
.classpath("morphia-core"))
.imports(Limit.class.getName())
.build();
private static final JavaTemplate MATCH = (JavaTemplate.builder("Match.match()"))
.javaParser(JavaParser.fromJavaVersion()
.classpath("morphia-core"))
.imports(Filter.class.getName())
.imports(Match.class.getName())
.build();
private static final JavaTemplate SKIP = (JavaTemplate.builder("Skip.skip()"))
.javaParser(JavaParser.fromJavaVersion()
.classpath("morphia-core"))
.imports(Skip.class.getName())
.build();
private static final JavaTemplate SORT_BY_COUNT = (JavaTemplate.builder("SortByCount.sortByCount()"))
.javaParser(JavaParser.fromJavaVersion()
.classpath("morphia-core"))
.imports(SortByCount.class.getName())
.build();

@Override
public @NotNull String getDisplayName() {
Expand Down Expand Up @@ -115,8 +136,6 @@ public boolean matches(@Nullable MethodCall methodCall) {
invocation = invocation.withName(methodInvocation.getName().withSimpleName("pipeline"))
.withArguments(arguments);

after = invocation.getPadding().getSelect().getAfter();

return maybeAutoFormat(methodInvocation, invocation
.withPrefix(Space.build("\n", emptyList())), context);
} else {
Expand All @@ -125,16 +144,26 @@ public boolean matches(@Nullable MethodCall methodCall) {
}

private void collectArguments(List<Expression> args, MethodInvocation invocation) {
if (invocation.getSimpleName().equals("match")) {
maybeAddImport(Match.class.getName(), "match", false);
MethodInvocation applied = MATCH.apply(new Cursor(getCursor(), invocation),
invocation.getCoordinates().replaceMethod());
args.add(0, applied.withArguments(invocation.getArguments()).withSelect(null));
} else {
args.addAll(0, invocation.getArguments());
switch (invocation.getSimpleName()) {
case "limit" -> collect(Limit.class, "limit", LIMIT, invocation, args);
case "match" -> collect(Match.class, "match", MATCH, invocation, args);
case "skip" -> collect(Skip.class, "skip", SKIP, invocation, args);
case "sortByCount" -> collect(SortByCount.class, "sortByCount", SORT_BY_COUNT, invocation, args);
default -> args.addAll(0, invocation.getArguments());
}
}

private void collect(Class<? extends Stage> type,
String method,
JavaTemplate template,
MethodInvocation invocation,
List<Expression> args) {
maybeAddImport(type.getName(), method, false);
MethodInvocation applied = template.apply(new Cursor(getCursor(), invocation),
invocation.getCoordinates().replaceMethod());
args.add(0, applied.withArguments(invocation.getArguments()).withSelect(null));
}

};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import org.openrewrite.Recipe;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.tree.Expression;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.J.ClassDeclaration;

public class UnwrapFieldExpressions extends Recipe {
@Override
Expand All @@ -24,13 +26,21 @@ public JavaVisitor<ExecutionContext> getVisitor() {
MethodMatcher valueMatcher = new MethodMatcher("dev.morphia.aggregation.expressions.Expressions value(..)");

return new JavaVisitor<>() {
@Override
public J visitClassDeclaration(ClassDeclaration classDecl, ExecutionContext executionContext) {
System.out.println("classDecl.getSimpleName() = " + classDecl.getSimpleName());
return super.visitClassDeclaration(classDecl, executionContext);
}

@Override
public J visitMethodInvocation(J.MethodInvocation method, @NotNull ExecutionContext context) {
if (fieldMatcher.matches(method) || valueMatcher.matches(method)) {
System.out.println("method = " + method);
maybeRemoveImport("dev.morphia.aggregation.expressions.Expressions.field");
maybeRemoveImport("dev.morphia.aggregation.expressions.Expressions.value");
return method.getArguments().get(0);
Expression expression = method.getArguments().get(0);
System.out.println("expression = " + expression);
return expression;
} else {
return super.visitMethodInvocation(method, context);
}
Expand Down
2 changes: 2 additions & 0 deletions rewrite/src/main/resources/META-INF/rewrite/rewrite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ recipeList:
filePattern: src/test/java/dev/morphia/test/MorphiaVersionTest.java
- org.openrewrite.DeleteSourceFiles:
filePattern: src/test/java/dev/morphia/test/mapping/experimental/MorphiaReferenceTest.java
- org.openrewrite.DeleteSourceFiles:
filePattern: src/test/java/dev/morphia/test/callbacks/TestInterceptors.java
- dev.morphia.rewrite.recipes.internal.RemoveMethodDeclaration:
methodPatterns:
- dev.morphia.test.TestDatastore testAlternateCollectionsWithLegacyQuery()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,84 @@ public MorphiaCursor<Document> update(Datastore ds) {
}
""".replace('#', ' ')));
}

@Test
public void testSkip() {
rewriteRun(java(
"""
import dev.morphia.Datastore;
import dev.morphia.query.MorphiaCursor;
import dev.morphia.query.filters.Filters;
import org.bson.Document;
public class UnwrapTest {
public MorphiaCursor<Document> update(Datastore ds) {
Object e2 = ds.aggregate(Object.class)
.skip(42)
.execute(Object.class)
.tryNext();
}
}
""",
//language=java
"""
import dev.morphia.Datastore;
import dev.morphia.query.MorphiaCursor;
import dev.morphia.query.filters.Filters;
import org.bson.Document;
import static dev.morphia.aggregation.stages.Skip.skip;
public class UnwrapTest {
public MorphiaCursor<Document> update(Datastore ds) {
Object e2 =#
ds.aggregate(Object.class)
.pipeline(
skip(42))
.execute(Object.class)
.tryNext();
}
}
""".replace('#', ' ')));
}

@Test
public void testSortByCount() {
rewriteRun(java(
"""
import dev.morphia.Datastore;
import dev.morphia.query.MorphiaCursor;
import dev.morphia.query.filters.Filters;
import org.bson.Document;
import static dev.morphia.aggregation.expressions.Expressions.field;
public class UnwrapTest {
public MorphiaCursor<Document> update(Datastore ds) {
Object e2 = ds.aggregate(Object.class)
.sortByCount(field("docs"))
.execute(Object.class)
.tryNext();
}
}
""",
"""
import dev.morphia.Datastore;
import dev.morphia.query.MorphiaCursor;
import dev.morphia.query.filters.Filters;
import org.bson.Document;
import static dev.morphia.aggregation.expressions.Expressions.field;
import static dev.morphia.aggregation.stages.SortByCount.sortByCount;
public class UnwrapTest {
public MorphiaCursor<Document> update(Datastore ds) {
Object e2 =#
ds.aggregate(Object.class)
.pipeline(
sortByCount(field("docs")))
.execute(Object.class)
.tryNext();
}
}
""".replace('#', ' ')));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,67 @@ public void update(Aggregation<?> aggregation) {
}
"""));
}

@Test
void unwrapsValueCalls() {
rewriteRun(
java(
"""
package dev.morphia;
import dev.morphia.aggregation.expressions.ComparisonExpressions;
import static dev.morphia.aggregation.stages.Projection.project;
import static dev.morphia.aggregation.expressions.Expressions.field;
import static dev.morphia.aggregation.expressions.Expressions.value;
import dev.morphia.aggregation.Aggregation;
import java.util.List;
import dev.morphia.aggregation.expressions.impls.Expression;
import static dev.morphia.aggregation.expressions.SetExpressions.allElementsTrue;
import static java.util.Arrays.asList;
public class UnwrapTest {
public void update(Aggregation<?> aggregation) {
assertAndCheckDocShape("{ $allElementsTrue: [ [ true, 1, 'someString' ] ] }",
allElementsTrue(value(List.of(value(true), value(1), value("someString")))), true);
assertAndCheckDocShape("{ $allElementsTrue: [ [ [ false ] ] ] }",
allElementsTrue(value(List.of(List.of(false)))), true);
assertAndCheckDocShape("{ $allElementsTrue: [ [ ] ] }",
allElementsTrue(value(List.of())), true);
assertAndCheckDocShape("{ $allElementsTrue: [ [ null, false, 0 ] ] }",
allElementsTrue(value(asList(null, false, 0))), false);
}
protected void assertAndCheckDocShape(String expectedString, Expression value, Object expectedValue) {
}
}
""",
"""
package dev.morphia;
import dev.morphia.aggregation.expressions.ComparisonExpressions;
import static dev.morphia.aggregation.stages.Projection.project;
import dev.morphia.aggregation.Aggregation;
import java.util.List;
import dev.morphia.aggregation.expressions.impls.Expression;
import static dev.morphia.aggregation.expressions.SetExpressions.allElementsTrue;
import static java.util.Arrays.asList;
public class UnwrapTest {
public void update(Aggregation<?> aggregation) {
assertAndCheckDocShape("{ $allElementsTrue: [ [ true, 1, 'someString' ] ] }",
allElementsTrue(List.of(true, 1, "someString")), true);
assertAndCheckDocShape("{ $allElementsTrue: [ [ [ false ] ] ] }",
allElementsTrue(List.of(List.of(false))), true);
assertAndCheckDocShape("{ $allElementsTrue: [ [ ] ] }",
allElementsTrue(List.of()), true);
assertAndCheckDocShape("{ $allElementsTrue: [ [ null, false, 0 ] ] }",
allElementsTrue(asList(null, false, 0)), false);
}
protected void assertAndCheckDocShape(String expectedString, Expression value, Object expectedValue) {
int x = 32;
}
}
"""));
}
}

0 comments on commit 9fde65a

Please sign in to comment.