Skip to content

Commit a791942

Browse files
committed
Be more verbose on comments regarding factorial resolve time fix
1 parent dd0a511 commit a791942

File tree

2 files changed

+20
-7
lines changed
  • javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts
  • javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver

2 files changed

+20
-7
lines changed

javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String na
195195
/**
196196
* Used where a symbol is being used (e.g. solving {@code x} when used as an argument {@code doubleThis(x)}, or calculation {@code return x * 2;}).
197197
* @param name the variable / reference / identifier used.
198-
* @param iterateAdjacentStmts flag to iterate adjacent statements, default to {@code true} except in cases to prevent repetitive checks.
198+
* @param iterateAdjacentStmts flag to iterate adjacent statements, should be set to {@code true} except when calling itself in order to prevent revisiting already visited symbols.
199199
* @return // FIXME: Better documentation on how this is different to solveSymbolAsValue()
200200
*/
201201
private SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, boolean iterateAdjacentStmts) {
@@ -258,8 +258,21 @@ private SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String n
258258
while(statementListIterator.hasPrevious()) {
259259
Context prevContext = JavaParserFactory.getContext(statementListIterator.previous(), typeSolver);
260260
if (prevContext instanceof StatementContext) {
261-
// Do not schedule each adjacent statement to do this exact same thing.
262-
// Since we are doing it here we will eventually cover all adjacent statements anyways.
261+
// We have an explicit check for "StatementContext" to prevent a factorial increase of visited statements.
262+
//
263+
// For example consider the following:
264+
// String a = "a";
265+
// String b = "b";
266+
// String c = get();
267+
//
268+
// If we simply call "prevContext.solveSymbol(name)" we will call the current method with the adjacent statement "prevContext".
269+
// Then "prevContext" will look at its previous adjacent statement. And so on and so forth.
270+
// When there are no more previous statements in this chain of method calls, we come back to here...
271+
// Then we look at the next "prevContext" which causes the entire process to start again.
272+
// This is how we get a factorial increase in calls to "solveSymbol".
273+
//
274+
// So what we do instead with this check is we pass in a flag to say "Do not look at previous adjacent statements".
275+
// Since each visited "prevContext" does not look at its adjacent statements we only visit each statement once in this while loop.
263276
symbolReference = ((StatementContext<?>)prevContext).solveSymbol(name, false);
264277
} else {
265278
symbolReference = prevContext.solveSymbol(name);

javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue3038Test.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
/**
1818
* An issue when resolving some name when there are a series of many prior {@link NodeWithStatements}s.
19-
* Each queues up solving in the prior adjacent statement, which means we queue up duplicate resolve calls.
19+
* Each queues up solving in the prior adjacent statement,
20+
* which means we queue up a factorial number of duplicate resolve calls.
2021
* <br>
21-
* Naturally this will result in an exponential growth in number of calls with the more prior statements.
22-
* If not fixed the example test cases below take hours to complete
23-
* <i>(They were tested and ran up to 75 minutes before manually being stopped)</i>.
22+
* This test verifies that parsing the given code below runs in an non-crazy amount of time <i>(Leeway for slow CI)</i>.
23+
* Without any fixes applied, this takes multiple hours to run.
2424
*/
2525
public class Issue3038Test extends AbstractResolutionTest {
2626
// In no way should this take more than 2.5 seconds

0 commit comments

Comments
 (0)