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

Analyse escaping for local vars #4658

Draft
wants to merge 71 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
7f55c3a
Visitor that can be used to find local variables that are leaking the…
MBoegers Nov 8, 2024
5a03ded
add licenses
MBoegers Nov 8, 2024
1088ccc
add support for ternary operators to FindVariablesEscapeLocation
MBoegers Nov 8, 2024
a38d727
Add visitor to easily determine, if a named variable will escape its …
MBoegers Nov 8, 2024
ea3bf6c
Update rewrite-java/src/test/java/org/openrewrite/java/search/FindVar…
timtebeek Nov 11, 2024
018669f
Merge branch 'main' into escape-analysis
timtebeek Nov 11, 2024
fd1a30c
FindEscapingVariablesTe
MBoegers Nov 12, 2024
9966a1b
Keep multiple whitelines and same comments from the gitignore file (#…
Jenson3210 Nov 11, 2024
cb0b4a7
Format JavaTemplateTest.addAnnotation to minimize review bot spam
timtebeek Nov 11, 2024
885dc51
Feature - YAML search - find properties with a specific scalar value …
aamotharald Nov 12, 2024
d01b739
Merge remote-tracking branch 'origin/main'
knutwannheden Apr 12, 2023
fd170d7
Update cursor-droping logic in RemoveMethodInvocationsVisitor
kunli2 Apr 12, 2023
749063f
update RemoveMethodInvocationsVisitor to work on java files only
kunli2 Apr 12, 2023
d560871
Update for rewrite 8.0 (#345)
knutwannheden May 31, 2023
f4967ef
Remove `private` modifiers from marker subtypes
knutwannheden Feb 20, 2024
43c2e02
Fix possible ClassCastException and cleanup warnings in NoRequestMapp…
sambsnyd Mar 14, 2024
2969c43
refactor: Move `@Nullable` method annotations to the return type
jkschneider Jul 16, 2024
6e86ee6
Migrate to JSpecify from OpenRewrite JSR-305 meta-annotations (#576)
jkschneider Aug 15, 2024
9119ea7
Merge remote-tracking branch 'origin/main'
knutwannheden Apr 12, 2023
5fd28c3
Perform recipe SelectRecipeExamples on rewrite-spring to select recip…
kunli2 Apr 26, 2023
e467242
Integrated with rewrite 7.40.3, update @DocumentExample package name
kunli2 Apr 26, 2023
8b9d397
Update for rewrite 8.0 (#345)
knutwannheden May 31, 2023
0ff762d
Fix compilation error
sambsnyd Nov 3, 2023
1c13f8b
refactor: Remove `public` visibility of JUnit 5 tests
timtebeek Feb 5, 2024
e3e2a19
relocating RemoveMethodInvocationsVisitor / Test to appropriate dir a…
nmck257 Nov 1, 2024
db497c5
adjusting RemoveMethodInvocationsVisitor super visit order to fix sup…
nmck257 Nov 1, 2024
a42419c
polishing nullability, documenting unsupported operation with test
nmck257 Nov 1, 2024
5efb642
quieting unused-method warnings
nmck257 Nov 1, 2024
0b4fdcc
simplifying boolean condition per intellisense
nmck257 Nov 1, 2024
e9b09cb
Apply suggestions from code review
nmck257 Nov 1, 2024
84bb741
fixing changes from robo code review
nmck257 Nov 1, 2024
1593b9e
Feature/remove unused properties (#4636)
nmck257 Nov 12, 2024
c621f80
wrapping RemoveMethodInvocationsVisitor into a recipe with streamline…
nmck257 Nov 12, 2024
36d76a5
Fixing the quoteEscaping test case for proper quote character escapin…
mccartney Nov 12, 2024
549521a
Fix SemanticallyEqual, and by extension SimplifyBooleanExpression, co…
sambsnyd Nov 13, 2024
a7b1d5a
Account for a second common resource filtering pattern (#4666)
timtebeek Nov 13, 2024
64845de
Update `ChangeType` and `ChangePackage` to work with `SourceFileWithR…
Laurens-W Nov 13, 2024
1923939
Update model for interfaces extending interfaces (#4663)
rlsanders4 Nov 13, 2024
14c9306
Fix condition where Attribute#getValue() throws an unsupported operat…
jkschneider Nov 13, 2024
2099691
Fix Javadoc for AnnotationService#getAllAnnotations(Cursor)
jkschneider Nov 14, 2024
3b6066f
Add new test and fix (#4672)
nielsdebruin Nov 14, 2024
5b1d46c
ChangeType does not work on J.ClassDeclaration (#4670)
rlsanders4 Nov 14, 2024
74f45a7
Refactor `ChangeType` tests to adhere to testing framework (#4673)
Laurens-W Nov 14, 2024
ae16af8
Add JavaDoc to ListUtils class
jevanlingen Nov 14, 2024
1247d42
Move project matcher to MavenVisitor (#4675)
ammachado Nov 14, 2024
618d2cf
Fix FindPlugins.find() throwing a class-cast exception if GString int…
sambsnyd Nov 15, 2024
aae6492
Fix Gradle AddDependency not doing anything when no onlyIfUsing param…
sambsnyd Nov 15, 2024
7052680
Remove redundant space for DeleteMethodArgument when argumentIndex=0 …
ckcd Nov 15, 2024
b174dcd
Also report `DeserializationError`s in `FindParseFailures` recipe
knutwannheden Nov 15, 2024
dde7882
Trim `RecipeDescriptor`s
knutwannheden Nov 15, 2024
64086ef
Slightly improve performance of `JsonPathMatcher`s
knutwannheden Nov 17, 2024
5201917
Improve performance of YAML `JsonPathMatcher`
knutwannheden Nov 17, 2024
cf3f27b
Improve performance of `JsonPathMatcher`s by only parsing once
knutwannheden Nov 17, 2024
37d24b3
`JsonPatchMatcher`: Replace Stream API with for-loops
knutwannheden Nov 17, 2024
221ea31
`JsonPatchMatcher`: Short-circuit matching when possible
knutwannheden Nov 17, 2024
95e9712
Fix accidental regression
knutwannheden Nov 17, 2024
9623d4a
Polish YAML `JsonPatchMatcher`
knutwannheden Nov 17, 2024
0b20b3b
Yet another YAML `JsonPatchMatcher` performance tweak
knutwannheden Nov 18, 2024
5e5ae55
Yet another YAML `JsonPatchMatcher` performance tweak
knutwannheden Nov 18, 2024
ec692b3
Allow YAML `JsonPatchMatcher` to match document-level sequences (#4680)
knutwannheden Nov 18, 2024
1a5ce2c
Append items to annotation attribute array (#4667)
nielsdebruin Nov 19, 2024
e30edf7
Polish `UpdateGradleWrapper`
knutwannheden Nov 20, 2024
8627e4c
Call isTrue on Reference asserts in XmlParserTest (#4689)
nielsdebruin Nov 20, 2024
88678ca
Fix NPE in SpringReference (#4691)
Laurens-W Nov 20, 2024
6836e29
Make `FindMissingTypes` stricter for method invocations (#4688)
knutwannheden Nov 20, 2024
832c12c
Make UpdateGradleWrapper.GradleWrapperState directly configurable
sambsnyd Nov 20, 2024
a29d6d5
Find Refaster style recipes as well (#4693)
timtebeek Nov 20, 2024
8c15566
refactor: Update Gradle wrapper
shanman190 Nov 20, 2024
5821fbf
Find Yaml recipes as well (#4695)
timtebeek Nov 20, 2024
0bf6212
Add find source files negation test.
sambsnyd Nov 21, 2024
dfc69df
`TypeUtils#isAssignable()` improvements (#4696)
knutwannheden Nov 21, 2024
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
Prev Previous commit
Next Next commit
JsonPatchMatcher: Replace Stream API with for-loops
  • Loading branch information
knutwannheden authored and MBoegers committed Dec 18, 2024
commit 37d24b3d9292599e1dcd9385c2cf476823e66bb4
157 changes: 80 additions & 77 deletions rewrite-yaml/src/main/java/org/openrewrite/yaml/JsonPathMatcher.java
Original file line number Diff line number Diff line change
@@ -33,7 +33,6 @@
import java.util.*;
import java.util.function.BiPredicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static java.util.Collections.disjoint;

@@ -164,15 +163,21 @@ protected Object aggregateResult(Object aggregate, Object nextResult) {

@Override
public Object visitJsonPath(JsonPathParser.JsonPathContext ctx) {
MATCH:
if (ctx.ROOT() != null || ctx.start.getType() == JsonPathLexer.LBRACK) {
scope = cursorPath.stream()
.filter(t -> t instanceof Yaml.Mapping)
.findFirst()
.orElseGet(() -> cursorPath.stream()
.filter(t -> t instanceof Yaml.Document && ((Yaml.Document) t).getBlock() instanceof Yaml.Mapping)
.map(t -> ((Yaml.Document) t).getBlock())
.findFirst()
.orElse(null));
for (Tree tree : cursorPath) {
if (tree instanceof Yaml.Mapping) {
scope = tree;
break MATCH;
}
}
for (Tree t : cursorPath) {
if (t instanceof Yaml.Document && ((Yaml.Document) t).getBlock() instanceof Yaml.Mapping) {
scope = ((Yaml.Document) t).getBlock();
break MATCH;
}
}
scope = null;
}
return super.visitJsonPath(ctx);
}
@@ -228,9 +233,11 @@ private JsonPathParser.ExpressionContext getExpressionContext(ParserRuleContext
}

// Return a list if more than 1 property is specified.
return ctx.property().stream()
.map(this::visitProperty)
.collect(Collectors.toList());
List<Object> list = new ArrayList<>();
for (JsonPathParser.PropertyContext propertyContext : ctx.property()) {
list.add(visitProperty(propertyContext));
}
return list;
} else if (ctx.slice() != null) {
return visitSlice(ctx.slice());
} else if (ctx.indexes() != null) {
@@ -260,7 +267,7 @@ public Object visitSlice(JsonPathParser.SliceContext ctx) {

// A wildcard will use these initial values, so it is not checked in the conditions.
int start = 0;
int limit = Integer.MAX_VALUE;
int limit = results.size();

if (ctx.PositiveNumber() != null) {
// [:n], Selects the first n elements of the array.
@@ -276,10 +283,7 @@ public Object visitSlice(JsonPathParser.SliceContext ctx) {
limit = ctx.end() != null ? Integer.parseInt(ctx.end().getText()) + 1 : limit;
}

return results.stream()
.skip(start)
.limit(limit)
.collect(Collectors.toList());
return results.subList(start, Math.min(start + limit, results.size()));
}

@Override
@@ -356,36 +360,31 @@ public Object visitIndexes(JsonPathParser.IndexesContext ctx) {
scope = member.getValue();
return visitProperty(ctx);
} else if (scope instanceof Yaml.Sequence) {
Object matches = ((Yaml.Sequence) scope).getEntries().stream()
.map(o -> {
scope = o;
return visitProperty(ctx);
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
List<Object> matches = new ArrayList<>();
for (Yaml.Sequence.Entry entry : ((Yaml.Sequence) scope).getEntries()) {
scope = entry;
Object result = visitProperty(ctx);
if (result != null) {
matches.add(result);
}
}
return getResultFromList(matches);
} else if (scope instanceof Yaml.Sequence.Entry) {
Yaml.Sequence.Entry entry = (Yaml.Sequence.Entry) scope;
scope = entry.getBlock();
return visitProperty(ctx);
} else if (scope instanceof List) {
List<Object> results = ((List<Object>) scope).stream()
.map(o -> {
scope = o;
return visitProperty(ctx);
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
// Unwrap lists of results from visitProperty to match the position of the cursor.
List<Object> matches = new ArrayList<>();
for (Object result : results) {
for (Object object : ((List<Object>) scope)) {
scope = object;
Object result = visitProperty(ctx);
if (result instanceof List) {
// Unwrap lists of results from visitProperty to match the position of the cursor.
matches.addAll(((List<Object>) result));
} else {
matches.add(result);
}
}

return getResultFromList(matches);
}

@@ -401,25 +400,27 @@ public Object visitIndexes(JsonPathParser.IndexesContext ctx) {
Yaml.Mapping.Entry member = (Yaml.Mapping.Entry) scope;
return member.getValue();
} else if (scope instanceof Yaml.Sequence) {
Object matches = ((Yaml.Sequence) scope).getEntries().stream()
.map(o -> {
scope = o;
return visitWildcard(ctx);
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
List<Object> matches = new ArrayList<>();
for (Yaml.Sequence.Entry entry : ((Yaml.Sequence) scope).getEntries()) {
scope = entry;
Object result = visitWildcard(ctx);
if (result != null) {
matches.add(result);
}
}
return getResultFromList(matches);
} else if (scope instanceof Yaml.Sequence.Entry) {
Yaml.Sequence.Entry entry = (Yaml.Sequence.Entry) scope;
return entry.getBlock();
} else if (scope instanceof List) {
List<Object> results = ((List<Object>) scope).stream()
.map(o -> {
scope = o;
return visitWildcard(ctx);
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
List<Object> results = new ArrayList<>();
for (Object object : ((List<Object>) scope)) {
scope = object;
Object result = visitWildcard(ctx);
if (result != null) {
results.add(result);
}
}

List<Object> matches = new ArrayList<>();
if (stop != null && stop == getExpressionContext(ctx)) {
@@ -490,21 +491,17 @@ public Object visitLiteralExpression(JsonPathParser.LiteralExpressionContext ctx
return getResultFromList(entry.getBlock());
}
} else if (scope instanceof List) {
List<Object> results = ((List<Object>) scope).stream()
.map(o -> {
scope = o;
return visitUnaryExpression(ctx);
})
.filter(Objects::nonNull)
.collect(Collectors.toList());

// Unwrap lists of results from visitUnaryExpression to match the position of the cursor.
List<Object> matches = new ArrayList<>();
for (Object result : results) {
if (result instanceof List) {
matches.addAll(((List<Object>) result));
} else {
matches.add(result);
for (Object object : ((List<Object>) scope)) {
scope = object;
Object result = visitUnaryExpression(ctx);
if (result != null) {
if (result instanceof List) {
// Unwrap lists of results from visitUnaryExpression to match the position of the cursor.
matches.addAll(((List<Object>) result));
} else {
matches.add(result);
}
}
}

@@ -557,11 +554,13 @@ public Object visitLiteralExpression(JsonPathParser.LiteralExpressionContext ctx
Yaml.Mapping.Entry entry = (Yaml.Mapping.Entry) lhs;
if (entry.getValue() instanceof Yaml.Sequence) {
Yaml.Sequence sequence = (Yaml.Sequence) entry.getValue();
if (sequence.getEntries().stream()
.filter(o -> o.getBlock() instanceof Yaml.Scalar)
.map(o -> (Yaml.Scalar) o.getBlock())
.anyMatch(o -> o.getValue().contains(String.valueOf(rhs)))) {
return originalScope;
for (Yaml.Sequence.Entry o : sequence.getEntries()) {
if (o.getBlock() instanceof Yaml.Scalar) {
Yaml.Scalar block = (Yaml.Scalar) o.getBlock();
if (block.getValue().contains(String.valueOf(rhs))) {
return originalScope;
}
}
}
} else if (entry.getValue() instanceof Yaml.Scalar) {
Yaml.Scalar scalar = (Yaml.Scalar) entry.getValue();
@@ -616,8 +615,8 @@ public Object visitLiteralExpression(JsonPathParser.LiteralExpressionContext ctx
scope = scopeOfLogicalOp;
rhs = getBinaryExpressionResult(rhs);
if ("&&".equals(operator) &&
((lhs != null && (!(lhs instanceof List) || !((List<Object>) lhs).isEmpty())) &&
(rhs != null && (!(rhs instanceof List) || !((List<Object>) rhs).isEmpty())))) {
((lhs != null && (!(lhs instanceof List) || !((List<Object>) lhs).isEmpty())) &&
(rhs != null && (!(rhs instanceof List) || !((List<Object>) rhs).isEmpty())))) {
// Return the result of the evaluated expression.
if (lhs instanceof Yaml) {
return rhs;
@@ -631,8 +630,8 @@ public Object visitLiteralExpression(JsonPathParser.LiteralExpressionContext ctx
}
return scopeOfLogicalOp;
} else if ("||".equals(operator) &&
((lhs != null && (!(lhs instanceof List) || !((List<Object>) lhs).isEmpty())) ||
(rhs != null && (!(rhs instanceof List) || !((List<Object>) rhs).isEmpty())))) {
((lhs != null && (!(lhs instanceof List) || !((List<Object>) lhs).isEmpty())) ||
(rhs != null && (!(rhs instanceof List) || !((List<Object>) rhs).isEmpty())))) {
return scopeOfLogicalOp;
}
} else if (ctx.EQUALITY_OPERATOR() != null) {
@@ -703,14 +702,14 @@ public Object visitLiteralExpression(JsonPathParser.LiteralExpressionContext ctx
Yaml.Mapping mapping = (Yaml.Mapping) lhs;
for (Yaml.Mapping.Entry entry : mapping.getEntries()) {
if (entry.getValue() instanceof Yaml.Scalar &&
checkObjectEquality(((Yaml.Scalar) entry.getValue()).getValue(), operator, rhs)) {
checkObjectEquality(((Yaml.Scalar) entry.getValue()).getValue(), operator, rhs)) {
return mapping;
}
}
} else if (lhs instanceof Yaml.Mapping.Entry) {
Yaml.Mapping.Entry entry = (Yaml.Mapping.Entry) lhs;
if (entry.getValue() instanceof Yaml.Scalar &&
checkObjectEquality(((Yaml.Scalar) entry.getValue()).getValue(), operator, rhs)) {
checkObjectEquality(((Yaml.Scalar) entry.getValue()).getValue(), operator, rhs)) {
return entry;
}
} else if (lhs instanceof Yaml.Scalar) {
@@ -780,10 +779,14 @@ private Object getResultFromList(Object results) {
} else if (result instanceof Yaml.Mapping) {
return ((Yaml.Mapping) result).getEntries();
} else if (result instanceof List) {
return ((List<Object>) result).stream()
.map(this::getValue)
.filter(Objects::nonNull)
.collect(Collectors.toList());
List<Object> list = new ArrayList<>();
for (Object o : ((List<Object>) result)) {
Object value = getValue(o);
if (value != null) {
list.add(value);
}
}
return list;
} else if (result instanceof Yaml.Sequence) {
return ((Yaml.Sequence) result).getEntries();
} else if (result instanceof Yaml.Scalar) {