ExpressionUtils { public static boolean isInvocationOnVariable(MethodInvocationTree mit, @Nullable Symbol variable, boolean defaultReturn) { ExpressionTree methodSelect = mit.methodSelect(); if (variable == null || !methodSelect.is(Tree.Kind.MEMBER_SELECT)) { return defaultReturn; } return extractIdentifierSymbol(((MemberSelectExpressionTree) methodSelect).expression()) .map(variable::equals) .orElse(defaultReturn); } private  ExpressionUtils(); static boolean isSimpleAssignment(AssignmentExpressionTree tree); static boolean isSelectOnThisOrSuper(AssignmentExpressionTree tree); static boolean isSelectOnThisOrSuper(MemberSelectExpressionTree tree); static IdentifierTree extractIdentifier(AssignmentExpressionTree tree); static Optional<Symbol> extractIdentifierSymbol(ExpressionTree tree); static boolean isInvocationOnVariable(MethodInvocationTree mit, @Nullable Symbol variable, boolean defaultReturn); static ExpressionTree skipParentheses(ExpressionTree tree); static boolean isNullLiteral(ExpressionTree tree); static boolean isSecuringByte(ExpressionTree expression); static IdentifierTree methodName(MethodInvocationTree mit); @CheckForNull static MethodTree getEnclosingMethod(ExpressionTree expr); static Optional<Symbol> getAssignedSymbol(ExpressionTree exp); static boolean isThis(ExpressionTree expression); @CheckForNull static Object resolveAsConstant(ExpressionTree tree);  }
@Test void test_invocation_on_same_variable() { CompilationUnitTree tree = JParserTestUtils.parse( "class A {\n" + " static {\n" + " String s1 = \"a\";" + " String s2 = \"b\";" + " s1.toString();\n" + " s2.toString();\n" + " toString();\n" + " Optional.of(s1).get().toString();\n" + " Optional.of(s2).get().toString();\n" + " }\n" + "}"); StaticInitializerTree staticInitializer = (StaticInitializerTree) ((ClassTree) tree.types().get(0)).members().get(0); List<Symbol> variablesSymbols = staticInitializer.body().stream() .filter(t -> t instanceof VariableTree) .map(VariableTree.class::cast) .map(VariableTree::symbol) .collect(Collectors.toList()); List<MethodInvocationTree> invocations = staticInitializer.body().stream() .filter(t -> t instanceof ExpressionStatementTree) .map(ExpressionStatementTree.class::cast) .map(ExpressionStatementTree::expression) .map(MethodInvocationTree.class::cast) .collect(Collectors.toList()); assertThat(isInvocationOnVariable(invocations.get(0), variablesSymbols.get(0), true)).isTrue(); assertThat(isInvocationOnVariable(invocations.get(0), variablesSymbols.get(1), true)).isFalse(); assertThat(isInvocationOnVariable(invocations.get(1), variablesSymbols.get(0), true)).isFalse(); assertThat(isInvocationOnVariable(invocations.get(1), variablesSymbols.get(1), true)).isTrue(); assertThat(isInvocationOnVariable(invocations.get(2), variablesSymbols.get(0), true)).isTrue(); assertThat(isInvocationOnVariable(invocations.get(2), variablesSymbols.get(1), true)).isTrue(); assertThat(isInvocationOnVariable(invocations.get(3), variablesSymbols.get(0), true)).isTrue(); assertThat(isInvocationOnVariable(invocations.get(3), variablesSymbols.get(1), true)).isTrue(); assertThat(isInvocationOnVariable(invocations.get(4), variablesSymbols.get(0), true)).isTrue(); assertThat(isInvocationOnVariable(invocations.get(4), variablesSymbols.get(1), true)).isTrue(); assertThat(isInvocationOnVariable(invocations.get(2), variablesSymbols.get(0), false)).isFalse(); assertThat(isInvocationOnVariable(invocations.get(2), variablesSymbols.get(1), false)).isFalse(); assertThat(isInvocationOnVariable(invocations.get(3), variablesSymbols.get(0), false)).isFalse(); assertThat(isInvocationOnVariable(invocations.get(3), variablesSymbols.get(1), false)).isFalse(); assertThat(isInvocationOnVariable(invocations.get(4), variablesSymbols.get(0), false)).isFalse(); assertThat(isInvocationOnVariable(invocations.get(4), variablesSymbols.get(1), false)).isFalse(); assertThat(isInvocationOnVariable(invocations.get(4), null, false)).isFalse(); assertThat(isInvocationOnVariable(invocations.get(4), null, true)).isTrue(); }